ios-Category

来源:互联网 发布:创业项目ppt运营数据 编辑:程序博客网 时间:2024/05/22 08:25
Category其实就是对一个类做一次扩展,一个类可以有很多扩展,在Category中我们是给这个类可以增加一个方法。常见的形式就是文件名为Car+extend.h类似于这样的,还有就是为什么我们在做扩展的时候要在Car+extend.h中要加一个#import "Car.h"这样的一个头文件呢?为什么不可以加一个@class?,那是因为,我们是给这个类扩展的是方法,而不是说我们仅仅用到这个类的声明,我们要知道这个Car类中的方法,看看我这个扩展类有没有跟它一样的方法。在我们的分类中只能扩展方法,不能添加成员变量。Category其实可以让类的方法模块化,把不同的类的方法分到了各个分类文件中。我们其实也可以直接把Car的扩展写在它的头文件中也就是说我们其实只需要在Car.h文件中加一个interface其实就可以,然后在.m文件中在加一个这个扩展的实现就可以了。比如说这样子
//在Car.h文件中#import <Foundation/Foundation.h>@interface Car:NSObject-(void)test;@end@interface Car(Extend)-(void)test1;@end
//在Car.m文件中#impore "Car.h"@implementation Car-(void)test{}@end@implementation Car(Extend)-(void)test1{    }@end
在我们的Category中是不可以创建实例变量的,但是可以声明一个属性,可以从Category的结构体来进行分析
typedef struct category_t { const char *name; //类的名字 classref_t cls; //类 struct method_list_t *instanceMethods; //category中所有给类添加的实例方法的列表 struct method_list_t *classMethods; //category中所有添加的类方法的列表 struct protocol_list_t *protocols; //category实现的所有协议的列表 struct property_list_t *instanceProperties; //category中添加的所有属性 } category_t;
Category的可以添加实例方法,类方法,可以实现协议,添加属性,但是无法添加实例变量。

实际上,Category实际上允许添加属性的,同样可以使用@property,但是不会生成_变量(带下划线的成员变量),也不会生成添加属性的getter和setter方法,所以,尽管添加了属性,也无法使用点语法调用getter和setter方法。那我们想要实现我们平时的属性所具有的功能应该怎么样做呢?
其实我们可以使用runtime去做,使用runtime去实现Category为已有的类添加新的属性并生成getter和setter方法。不要忘记了Objective-C是动态语言。方法是通过runtime.h中objc_getAssociatedObject / objc_setAssociatedObject来访问和生成关联对象。这两个方法可以让一个对象和另一个对象关联,就是说一个对象可以保持对另一个对象的引用,并获取那个对象。
@interface UIImage (extend)@property (nonatomic, strong) NSString *string;@end
#import "UIImage+Extend.h" #import <objc/runtime.h> static char *StringKey = "StringKey"//static const void *Key = &Key;//此处也可以是@implementation UIImage (Extend) @dynamic string; - (NSString *)string{return objc_getAssociatedObject(self, StringKey);}- (void)setString:(NSString *)string{objc_setAssociatedObject(self, StringKey, string, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end
关联方法:
     objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
参数解析
 id object 给哪个对象的属性赋值
     const void *key 属性对应的key
     id value  设置属性值为value
     objc_AssociationPolicy policy  使用的策略,是一个枚举值
     enum {
    OBJC_ASSOCIATION_ASSIGN = 0, //关联对象的属性是弱引用
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //关联对象的属性是强引用并且关联对象不使用原子性
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //关联对象的属性是copy并且关联对象不使用原子性
    OBJC_ASSOCIATION_RETAIN = 01401, //关联对象的属性是copy并且关联对象使用原子性
    OBJC_ASSOCIATION_COPY = 01403 //关联对象的属性是copy并且关联对象使用原子性
};
    属性对应的key也可以这怎么写
    利用静态变量地址唯一不变的特性
    1、static void *strKey = &strKey;

    2、static NSString *strKey = @"strKey";

    3、static char strKey;
 */

参考:http://www.jianshu.com/p/535d1574cb86



原创粉丝点击