为UIviewcontroller扩展类添加全局变量

很多说法是只能添加方法,而不能添加成员变量或属性。

有些人可能知道,这种说法是不严谨的,并不是绝对不能添加变量。

解释如下:

我们知道在一个类中用@property声明属性,编译器会自动帮我们生成_成员变量和setter/getter,但分类的指针结构体中,根本没有属性列表。所以在分类中用@property声明属性,既无法生成_成员变量也无法生成setter/getter。

因此结论是:我们可以用@property声明属性,编译会通过,但run之后就会崩溃。


问题来了。。

既然报错的根本原因是使用了系统没有生成的setter/getter方法,可不可以在手动添加setter/getter来避免崩溃,完成调用呢?

其实是可以的。由于OC是动态语言,方法真正的实现是通过runtime完成的,虽然系统不给我们生成setter/getter,但我们可以通过runtime手动添加setter/getter方法。那具体怎么实现呢?

举例如下:

分类.h

#import"Programmer.h"@interface Programmer (Category)

@property(nonatomic,copy) NSString *nameWithSetterGetter;//设置setter/getter方法的属性- (void) programCategoryMethod;//分类方法@end

分类.m

#import"Programmer+Category.h"

#import

static NSString *nameWithSetterGetterKey =@"nameWithSetterGetterKey";@implementation Programmer (Category)

- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter {

        objc_setAssociatedObject(self, &nameWithSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY);

}- (NSString *)nameWithSetterGetter {

    returnobjc_getAssociatedObject(self, &nameWithSetterGetterKey);

}- (void)programCategoryMethod {

    NSLog(@"实现分类方法");

}

@end

重点就是两个runtime实现方法,如果不写这个,只要你申明了属性,运行肯定会报错;如果加了这两个方法,就能运行通过了,而且,我们在其他地方也能正常使用了

Programmer *programmer = [[Programmer alloc]init];


    //通过runtime实现了setter/getterprogrammer.nameWithSetterGetter =@"有setter/getter";//调用setter,成功NSLog(@"%@",programmer.nameWithSetterGetter);//调用getter,成功

你可能感兴趣的:(为UIviewcontroller扩展类添加全局变量)