OC学习日记012(二)类目、延展

来源:互联网 发布:网络歌手男歌手 编辑:程序博客网 时间:2024/06/06 05:29

类目、延展

这里写图片描述

前言

类目跟延展都是为了为现有的类去扩展新的方法而存在的,因为我们程序的开发要符合我们之前所说的开闭原则(对扩展开放,对修改关闭),而类目主要为了去为我们的类去扩展共有的方法,延展是为了去扩展私有的方法。

类目:

定义:

 为现有工程中的类和系统类添加新的方法

作用:

在类目中添加新的方法及属性和在原类中添加方法和属性是一样的,都能够被类和类的子类调用。在类目中为原类添加新的方法和属性

类目的使用场景

 1.类包含了很多个方法实现,而这些方法需要不同团队成员来实现 2.当你在使用基础类库中的类时,你不想继承这些类而指向添加一些方法时

使用类目时的时候需要注意的问题

 1.类目可以访问原始类的实例变量,但不能添加实例变量,如果添加实例变量,那就通过继承创建子类实现。 2.类目可以重载原始类的方法,但不推荐这么做,这样会覆盖掉原始类的方法,如果确实要重载,那就通过继承创建子类来实现。 3.和普通接口有所区别的是,在类目的实现文件中的实例方法只要你不去调用它你可以不用实现所有声明的所有方法

以下是为类添加类目的例子:

(一般在原有的文件下方写或者新建一个类目文件进行书写,并表明是哪个类的类目。)
这里写图片描述
以下是一个Tool类的原始类的接口文件与方法文件:

Tool.h

//原始类方法@interface Tool : NSObject{    NSString *_name;}@property (nonatomic,strong)NSString *property1;-(void)function1;@end

Tool.m

@implementation Tool-(void)function1{    NSLog(@"I am funtion1");}@end

Tool(Category部分).h

@interface Tool (ToolCategory)//{//  类目中不能添加实例变量    //NSString *_adas;//}//-(void)function1;//不推荐重载原始类的方法!-(void)function2;@end

Tool(Category部分).m

@implementation Tool (ToolCategory)//-(void)function1{//    //    NSLog(@"我是类目中的function1");//}-(void)function2{    NSLog(@"%@",_name);    NSLog(@"I am function2");    NSLog(@"%@",self.property2);}

外置类目文件:(Tool+ToolCategory.h)

@interface Tool (ToolCategory)-(void)function3;@end

外置类目文件:(Tool+ToolCategory.m)

@implementation Tool (ToolCategory)-(void)function3{    NSLog(@"我是function3");}@end

进阶知识:

我们知道类目里面不可以添加新的实例变量,会报错;如果我们往类目里面添加一个新的属性呢?我们会发现,系统是不会报错的。那是不是可以添加属性呢?但是,到我们在主函数里面设置还有访问该属性的时候,就会报错。那怎么解决呢?其实就像我们开始学设置器和访问器一样,重写设置器和访问器,但这里不是普通的重写,这里就要用到我们IOS的一套机制了,即运行时机制。

运行时机制

 IOS运行时机制,简单来说,苹果为开发者提供的一套运行时动态创建类、方法、属性、的API,它是一套纯c语言的API。

首先我们先随便设置一个属性:

@property (nonatomic,strong)NSString *property2;

之后我们在.m文件的类目里面重写getter和setter方法:

设置器我们要用到 objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)方法

该方法要写入的属性对应如下:     <#id object#>   :给哪个对象的属性赋值     <#const void *key#> :属性对应的key     <#id value#> : 设置属性值为value     <#objc_AssociationPolicy policy#> : 使用的策略

访问器我们要用到objc_getAssociatedObject(<#id object#>, <#const void *key#>)方法。

    该方法要写入的属性对应如下:     <#id object#>   :给哪个对象的属性赋值     <#const void *key#> :属性对应的key
 -(void)setProperty2:(NSString *)property2{    //_property2=property2;    objc_setAssociatedObject(self, @selector(property2), property2, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}-(NSString *)property2{//    return _property2;    return objc_getAssociatedObject(self, @selector(property2));}

最后我们在主函数看看类目里面的方法和属性的效果实现了没:
ViewControl.m文件:

    Tool *tool=[[Tool alloc]init];    [tool function1];    [tool setValue:@"Rick" forKey:@"_name"];    [tool setValue:@"aaa" forKey:@"property2"];    [tool function2];    [tool function3];

延展

我们之前说过类目可以添加私有的方法,其实指的是匿名类目,也就是延展。

作用

 延展的作用就是定义自己的私有方法

类目跟接口文件很像,就是把继承父类那一块换成一对小括号,表明它是一个延展(匿名类目)

@interface MyClass ()-(void)testExtension;@end

这里写图片描述

下面是例子:

#import "MyClass.h"#import "Myclass_Extension.h"#pragma mark ---------------------------------@interface MyClass ()-(void)testExtension;@end#pragma mark ---------------------------------@implementation MyClass-(void)test1{    NSLog(@"test1");}-(void)test2{    NSLog(@"test2");    [self testExtension];    [self testExtension2];}-(void)testExtension{    NSLog(@"我是延展testExtension");}-(void)testExtension2{    NSLog(@"我是延展testExtension2");}@end

外置延展文件:(Myclass_Extension.h)

#import "MyClass.h"@interface MyClass ()-(void)testExtension2;@end

这里写图片描述

0 0
原创粉丝点击