4

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

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

4

3 回答 3

7

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

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

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

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

于 2012-10-16T18:17:25.670 回答
1

Actually I don't know when we were able to add property in categories.

From Apple Docs:

A category allows you to add methods to an existing class—even to one for which you do not have the source.

and

Class extensions are like anonymous categories, except that the methods they declare must be implemented in the main @implementation block for the corresponding class. Using the Clang/LLVM 2.0 compiler, you can also declare properties and instance variables in a class extension.

and this method is used to add storage to an object without modifying the class declaration (in case you couldn't modify or don't have access to source codes of class)

Associative references, available starting in OS X v10.6, simulate the addition of object instance variables to an existing class. Using associative references, you can add storage to an object without modifying the class declaration. This may be useful if you do not have access to the source code for the class, or if for binary-compatibility reasons you cannot alter the layout of the object.

So your question for me seems to be incorrect.

Source: Apple Docs - The Objective-C Programming Language

于 2012-10-16T18:19:05.743 回答
0

正如其他人所说,这样做的方法是使用关联引用。它们的实现很像 CALayer's value / key-pair 范例.. 基本上.. 你可以“关联”任何东西,与任何“属性”或“事物”......</p>

因此,在您的类别标题中……如果您只想读取一个值……

@property (只读) NSString *uniqueID;

然后写你的吸气剂……</p>

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

但是说..你不能只从你的getter中得出值..你需要存储外部setter……或者类自己的实现来使用……你必须写一个像……这样的setter

- (void) setUniqueID:(NSString*)uId 

它不一定是公开的……但这就是“魔法”发生的地方。

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

看了这个之后我意识到,我正在使用一些“个人类别”来帮助简化这些值的设置和获取等。所以我把它们发布到这个 gist上,因为它们非常有用..并且包括像……这样的小宝石</p>

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

“得到它”的秘诀是“政策”部分。这些价值观......</p>

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

捕获与在“正常”声明中描述您的属性时所表达的相同的“个性”特征。您必须告诉编译器如何使用相同的规则“存储”您的值,然后您就可以开始了。

于 2013-04-10T18:53:55.330 回答