测试已测试 | ✓ |
语言语言 | Obj-CObjective C |
许可证 | MIT |
发布上次发布 | 2015年7月 |
由 Jonathan Crooke 维护。
关联对象(或关联引用)是在 OS X 10.6 和 iOS 4.0 中引入的。这个特性给类实例提供了一个字典,可以在其中使用运行时函数 objc_setAssociatedObject()
和 objc_getAssociatedObject()
存储任意对象。本项目旨在让它们的使用更加方便,并以轻量级和彻底测试的方式实现。
为类别添加 ivars - 由于 Obj-C 分类不允许添加或合成 ivars,即使可以添加属性,这是一个不幸的缺点。关联对象可以用来提供存储,以克服这一限制
@interface NSObject (MyCategory)
@property (strong) id myCategoryObject;
@end
@implementation NSObject (MyCategory)
SYNTHESIZE_ASC_OBJ(myCategoryObject, setMyCategoryObject);
@end
NSObject 的任意字典 - NSObject
分类向 NSObject
添加了一个延迟初始化的 NSMutableDictionary
,允许将键值对方便地关联到任何 NSObject
子类实例
[self.associatedDictionary setValue:@"value" forKey:@"myKey"];
属性内存管理语义 - 由于属性使用关联对象进行存储,因此可以使用任何属性设置器语义
@property () id myProperty;
@property (strong) id myProperty;
@property (retain) id myProperty;
@property (assign) id myProperty;
@property (copy) id myProperty;
目前,宏在运行时检查对 NSCopying
协议的合规性,如果在找到的情况下使用 OBJC_ASSOCIATION_COPY
,否则使用 OBJC_ASSOCIATION_RETAIN
。测试 -[UnitTests testMutableObject]
确认已复制。我认为这是正确的方式。然而,最好还是使用这些设置器中的正常语义。
自版本 2.0.0
开始支持弱属性,其行为与常规 weak
属性相同。
提供的静态库用于 NSObject
分类,或仅使用头文件进行基本使用。建议使用 CocoaPods 进行安装。
pod 'ObjcAssociatedObjectHelpers'
提供了详尽的测试用例,覆盖率近 100%。
SYNTHESIZE_ASC_OBJ(getterName, setterName)
- 最基本的使用方法。为读写对象属性合成 getter 和 setter。如果你希望生成一个只有私有或保护 setter 的只读属性,可以在其他分类中定义。
@interface MyClass : NSObject
@property (readonly) id readWriteObject;
@end
@interface MyClass (PrivateOrProtectedOrAnonymous)
@property (readwrite) id readWriteObject;
@end
@implementaton MyClass
- (id) init {
if ((self = [super init])) {
self.readWriteObject = @"foo";
}
return self;
}
SYNTHESIZE_ASC_PRIMITIVE(getterName, setterName, type)
- 为任何类型的原始对象合成。支持任何由 @encode()
运算符支持的类型。所以应该...一切都是支持的?
SYNTHESIZE_ASC_OBJ_LAZY(getterName, class)
- 合成一个在首次访问时通过懒加载进行初始化的只读对象。必须提供对象类以便在首次访问时可以初始化(通过 alloc/init
)对象。SYNTHESIZE_ASC_OBJ_LAZY_EXP(getterName, initExpression)
- 合成一个在首次访问时懒加载进行初始化的只读对象,并提供一个初始化表达式。例如:
SYNTHESIZE_ASC_OBJ_LAZY_EXP(nonDefaultLazyObject, [NSString stringWithFormat:@"foo"])
使用表达式 [NSString stringWithFormat:@"foo"]
初始化对象。请注意 SYNTHESIZE_ASC_OBJ_LAZY
使用这个宏与 [[class alloc] init]
。
所有宏都有带有 _BLOCK
后缀的伴随宏,它(借用通用编程语法)接受一个类型为 T(^block)(T value)
的块,用于 getter 和 setter(如果可用)。这允许在访问器中运行额外的代码,类似于覆盖访问器。传递给访问器的值将是参数。这个值可以被返回,也可以返回一个修改后的值。这取代了直到 v1.2.1
所使用的语法,我认为这更清晰。例如
SYNTHESIZE_ASC_PRIMITIVE_BLOCK(myProperty,
setMyProperty,
CGSize,
^(CGSize s){ return CGSizeZero; },
^(CGSize s){ s.width = 10; return s; })
定义一个类型为 CGSize
的读写属性,并覆盖 getter 和 setter 以始终设置为 CGSizeZero
,并始终返回一个宽度为 10 的大小。
v2.0.1
weak
功能所必需的。v2.0.0
weak
属性添加了一个新功能,使用这里提供的包装方法在这里建议的方法。NSObject
分类现在有前缀并分解为一个子规范以用于 Cocoapods。v1.2.1
v1.2.0
v1.1.2
v1.1.1
self.property
将是现有值,在 新值被设置之前。v1.1
v1.0