@interface XXX : NSObject {
NSString *any;
}
与之比较:
objc_setAssociatedObject(self, "any", @"xxx", OBJC_ASSOCIATION_COPY);
它们都放在下面吗?
struct objc_ivar_list *ivars
答案 0 :(得分:0)
不,这些是不同的技术。
在编译时定义ivar,并且在分配实例时,为其分配内存空间。 (请记住,NSString*
是ivar的类型,因此分配了引用的内存空间,而不是NSString
本身的实例。)
关联存储在与实例相关的字典样式存储空间中。
但是,如果要设置一个值,仅在运行时知道其键,请使用键值编码:
[self setValue:@"xxx" forKey:@"any"];
这将执行setter -setAny:
,这可能会设置ivar。
声明声明的属性(@property
)是完全不同的。属性声明仅声明方法。如果在类或类继续中完成,则在某些情况下合成ivar。在一个类别中它永远不会被合成,因为如果在一个类别中合成是不可能的。
答案 1 :(得分:0)
我没有明确表达,这是我的错,我想知道当我使用关联时是否有新的ivar放入objc_ivar_list。现在我明白了.Thx.And。你告诉我,当我在一个班级及其类别中声明一个属性时是否存在任何差异?为什么这样设计 - Max Wang 12月17日7:51
抱歉,我没有足够的声誉来添加评论来回答这个问题。
让我告诉你类和类别中的属性之间的差异。如果在类中声明了属性,编译器将自动为此属性生成setter和getter方法,如您所知。但是,在类别中,即使您被允许为该类声明属性,编译也不会为您生成setter和getter方法。如果您尝试访问类别中声明的属性,Xcode将抛出*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[XXXX setSomeProperty:]: unrecognized selector sent to instance 0x798342c0'
,因为没有现有方法。这就是为什么我们需要objc_setAssociatedObject和objc_getAssociatedObject来手动生成setter和getter。