编译器是否会为类别中声明的属性自动合成ivar?

时间:2012-10-16 18:02:09

标签: objective-c objective-c-category declared-property

在所谓的“Modern Objective-C”之前,当在类别中创建新属性时,我们需要实现setter和getter方法。现在,我们不必做@synthesize;编译器将自动创建方法和实例变量。

但通常情况下,我们无法将实例变量添加到类别中,那么如果我们在具有现代Objective-C的类别中添加新属性会发生什么?编译器是否为我们创建了一个ivar?

3 个答案:

答案 0 :(得分:6)

您可以在类别中声明属性,这相当于声明getter和(如果是readwrite)setter选择器。

编译器将自动合成类别实现中的getter和setter方法。如果未在类别实现中明确定义它们,编译器将发出警告。您可以在类别实现中使用@dynamic来禁止警告。您不能在类别实现中使用@synthesize;如果你尝试,编译器会发出错误。

编译器不会为类别中声明的属性添加实例变量。您无法在类别中显式添加实例变量,也无法欺骗编译器使用属性执行此操作。

我使用针对iOS 6.0的Xcode 4.5.1测试了我的声明。

答案 1 :(得分:1)

实际上我不知道我们什么时候可以在类别中添加property

来自Apple Docs:

  

类别允许您将方法添加到现有类 - 甚至是您没有源的类。

  

扩展类似于匿名类别,除了它们声明的方法必须在相应类的主@implementation块中实现。使用Clang / LLVM 2.0编译器,您还可以在类扩展中声明属性实例变量

此方法用于将存储添加到对象而不修改类声明(如果您无法修改或无法访问源代码)班级)

  从OS X v10.6开始提供的

关联引用模拟对象实例变量添加到现有类。使用关联引用,可以在不修改类声明的情况下向对象添加存储。 如果您无法访问该类的源代码,或者由于二进制兼容性原因您无法更改该对象的布局,则此选项可能很有用。

所以你的问题似乎不正确。

来源:Apple Docs - The Objective-C Programming Language

答案 2 :(得分:0)

正如其他人所说,实现此目的的方法是使用 关联引用 。它们实现非常类似于 CALayer的价值/密钥对范式......基本上......你可以“关联”任何东西,任何“财产”或“东西”......

所以在你的类别标题中......如果你想做的只是读取一个值......

@property(readonly)NSString * uniqueID;

然后写下你的getter ......

- (NSString*) uniqueID { return @"You're not special"; }

但是说...你不能只是从你的getter中得到的价值......你需要存储外部的setter ......或者类的自己的实现才能使用......你必须写一个类似的setter。 ..

- (void) setUniqueID:(NSString*)uId 

它不一定是公开的,必然......但这就是“神奇”发生的地方。

 …
[self setAssociatedValue:uId forKey:@"yourInternalStorageName"
                  policy:OBJC_ASSOCIATION_RETAIN_NONATOMIC];

我在看了这个之后意识到,我正在使用一些“个人类别”来帮助简化这些值的设置和获取等等。所以I've posted them to this gist,因为它们非常有用..并且包括像...这样的小宝石。

- (id) associatedValueForKey:(NSString*)key 
                     orSetTo:(id)anObject 
                      policy:(objc_AssociationPolicy) policy;

“得到它”的秘诀是“政策”部分......这些价值......

OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403

捕获与在“正常”声明中描述属性时表达的相同“个性”特征。您必须告诉编译器如何使用相同的规则“存储”您的值,并且您将会很高兴。