Objective-C:在分类中添加属性

这两天在想着写一个自己的开源框架,类似MJRefresh那种。因为是自己第一个框架,也没有这方面的经验,还在摸索中。
  • 初步设想是给UIScrollview添加一个分类,在其中添加相关的属性和方法,但是在添加属性的时候遇到了些麻烦。比如以下:
#import <UIKit/UIKit.h>

@interface UITableViewController (ZLRefresh)

@property (nonatomic, strong) NSObject *object;

@end

此时编译器会报警告,大意是此分类无法合成属性的相关实例变量。

  • 查阅了相关资料,比如在《Effective Objective-C 2.0》中就提供了可以使用关联对象的方法实现在分类中添加属性(虽然作者在书中反复强调最好不要这么做...)。如下:

#import "UITableViewController+ZLRefresh.h"
#import <objc/runtime.h>

static const char* kObjectPropertyKey = "kObjectPropertyKey";

@implementation UITableViewController (ZLRefresh)
- (NSObject *)object{
    
    return objc_getAssociatedObject(self, kObjectPropertyKey);
    
}
- (void)setObject:(NSObject *)object{
    
    objc_setAssociatedObject(self,
                    kObjectPropertyKey,
                    object,
                    OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

PS:此处注意要导入<objc/runtime.h>这个头文件!

  • 好吧,我发现脑海中对这个所谓关联对象一点映像都木有QAQ,继续翻阅资料,在书中(依然是《Effective objc2.0》)找到如下:

    1. 可以给对象关联许多对象,这对象通过键来区分。

    2.在存储对象值得时候,可以指明“存储策略”(storage policy),用以维护相应的内存,(比如上面的OBJC_ASSOCIATION_RETAIN_NONATOMIC

3.可以用以下的方法管理关联对象:

  • void objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)
    此方法用以给定的键和策略为某对象设置关联对象值。
  • id objc_getAssociatedObject(<#id object#>, <#const void *key#>)
    此方法根据给定的键从某对象中获取相应的关联对象值。
  • objc_removeAssociatedObjects(<#id object#>)
    此方法用于移除指定对象的全部关联对象。
  • 可以看到这个所谓的关联对象和我们平时所使用的NSDictionary很像,但是作者也强调了,两者之间有个重要的区别:设置关联对象的key是个不透明的指针(void*)。比如在两个键上调用isEqual:方法返回的值是yes,那么dic就认为是二者相等;而然在设置关联对象值时,若想令两个键匹配到同一个值,则二者必须是完全相同的指针才可以。故设置关联对象的键通常是 静态全局变量
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容