声明:本文档仅为个人学习过程中顺手翻译之作,方便开发的同胞借鉴参考。如有觉得译的不好不到位的地方,欢迎指正,将及时做出更正
|
static char overviewKey; |
|
NSArray *array = |
[[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil]; |
// For the purposes of illustration, use initWithFormat: to ensure |
// the string can be deallocated |
NSString *overview = |
[[NSString alloc] initWithFormat:@"%@", @"First three numbers"]; |
|
objc_setAssociatedObject ( |
array, |
&overviewKey, |
overview, |
OBJC_ASSOCIATION_RETAIN |
); |
|
[overview release]; |
// (1) overview valid |
[array release]; |
// (2) overview invalid |
在(1)处, overview
字符串仍然是有效可用的,因为 OBJC_ASSOCIATION_RETAIN
原则指定了数组将保持这个相关的对象。当数组也被释放后,(2)的位置,overview
就也被释放了,此时所有的都将释放。要是你还试图去使用 overview
,就会报运行时异常。
通过使用 Objective-C 的运行时函数 objc_getAssociatedObject
可用获得一个关联对象。让我们继续 6-1 中的例子,你可以通过下面的代码从 array
中获取到overview
NSString *associatedObject = |
(NSString *)objc_getAssociatedObject(array, &overviewKey); |
要断开关联,你可以调用 objc_setAssociatedObject
, 传一个 nil。
继续使用 6-1的例子,你可以使用下面的代码断开array跟overview
字符串的关联:
objc_setAssociatedObject(array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN); |
关联的对象被设置为了 nil
, 至于原则项这里都不重要。
要断开一个对象的所有关联,你可以调用 objc_removeAssociatedObjects。
通常来说,不应该使用这个方法,因为它会对所有的客户断开所有关联。只有当你想把一个对象重置到初始化状态时再使用这个方法。
下面是本节完整的例子
#import <Foundation/Foundation.h> |
#import <objc/runtime.h> |
|
int main (int argc, const char * argv[]) { |
|
@autoreleasepool { |
static char overviewKey; |
|
NSArray *array = [[NSArray alloc] |
initWithObjects:@ "One", @"Two", @"Three", nil]; |
// For the purposes of illustration, use initWithFormat: to ensure |
// we get a deallocatable string |
NSString *overview = [[NSString alloc] |
initWithFormat:@"%@", @"First three numbers"]; |
|
objc_setAssociatedObject ( |
array, |
&overviewKey, |
overview, |
OBJC_ASSOCIATION_RETAIN |
); |
[overview release]; |
|
NSString *associatedObject = |
(NSString *) objc_getAssociatedObject (array, &overviewKey); |
NSLog(@"associatedObject: %@", associatedObject); |
|
objc_setAssociatedObject ( |
array, |
&overviewKey, |
nil, |
OBJC_ASSOCIATION_ASSIGN |
); |
[array release]; |
|
} |
return 0; |
} |
Associative references, available starting in Mac 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.
Associations are based on a key. For any object you can add as many associations as you want, each using a different key. An association can also ensure that the associated object remains valid for at least the lifetime of the source object.
You use the Objective-C runtime function objc_setAssociatedObject
to
make an association between one object and another. The function takes four parameters: the source object, a key, the value, and an association policy constant. Of these, the key and the association policy merit further discussion.
The key is a void
pointer. The key for each association must be unique. A typical pattern is to use a static
variable.
The policy specifies whether the associated object is assigned, retained, or copied, and whether the association is be made atomically or non-atomically. This pattern is similar to that of
the attributes of a declared property (see “Property
Declaration Attributes”). You specify the policy for the relationship using a constant (seeobjc_AssociationPolicy
and Associative
Object Behaviors
).
Listing 6-1 shows how you can establish an association between an array and a string.
Listing 6-1 Establishing an association between an array and a string
static char overviewKey; |
|
NSArray *array = |
[[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil]; |
// For the purposes of illustration, use initWithFormat: to ensure |
// the string can be deallocated |
NSString *overview = |
[[NSString alloc] initWithFormat:@"%@", @"First three numbers"]; |
|
objc_setAssociatedObject ( |
array, |
&overviewKey, |
overview, |
OBJC_ASSOCIATION_RETAIN |
); |
|
[overview release]; |
// (1) overview valid |
[array release]; |
// (2) overview invalid |
At point 1, the string overview
is still valid because the OBJC_ASSOCIATION_RETAIN
policy
specifies that the array retains the associated object. When the array is deallocated, however (at point 2), overview
is released and so in this case also deallocated. If you
try to, for example, log the value of overview
, you generate a runtime exception.
You retrieve an associated object using the Objective-C runtime function objc_getAssociatedObject
.
Continuing the example shown in Listing
6-1, you could retrieve the overview from the array using the following line of code:
NSString *associatedObject = |
(NSString *)objc_getAssociatedObject(array, &overviewKey); |
To break an association, you typically call objc_setAssociatedObject
, passing nil
as
the value.
Continuing the example shown in Listing
6-1, you could break the association between the array and the stringoverview
using the following line of code:
objc_setAssociatedObject(array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN); |
Given that the associated object is being set to nil
, the policy isn’t actually important.
To break all associations for an object, you can call objc_removeAssociatedObjects
.
In general, however, you are discouraged from using this function because it breaks all associations for all clients. Use this function only if you need to restore an object to “pristine condition.”
The following program combines code from the preceding sections.
#import <Foundation/Foundation.h> |
#import <objc/runtime.h> |
|
int main (int argc, const char * argv[]) { |
|
@autoreleasepool { |
static char overviewKey; |
|
NSArray *array = [[NSArray alloc] |
initWithObjects:@ "One", @"Two", @"Three", nil]; |
// For the purposes of illustration, use initWithFormat: to ensure |
// we get a deallocatable string |
NSString *overview = [[NSString alloc] |
initWithFormat:@"%@", @"First three numbers"]; |
|
objc_setAssociatedObject ( |
array, |
&overviewKey, |
overview, |
OBJC_ASSOCIATION_RETAIN |
); |
[overview release]; |
|
NSString *associatedObject = |
(NSString *) objc_getAssociatedObject (array, &overviewKey); |
NSLog(@"associatedObject: %@", associatedObject); |
|
objc_setAssociatedObject ( |
array, |
&overviewKey, |
nil, |
OBJC_ASSOCIATION_ASSIGN |
); |
[array release]; |
|
} |
return 0; |
} |
|
来自: 现在决定明天 > 《Objective-c官方文档》