- ARC is supported in Xcode 4.2 for OS X v10.6 and v10.7 (64-bit applications) and for iOS 4 and iOS 5. Weak references are not supported in OS X v10.6 and iOS 4.
- ARC 需要知道它的作用域,这样才能正确的释放这个对象。
- sortedResults 在 @autoreleasepool 的作用域中定义, 在它的外部不能被访问到。 为了修正这个问题,你需要将变量的定义放到创建 NSAutoreleasePool 的上面。
- You also need to take care with objects passed by reference. The following code will work:
NSError *error;
BOOL OK = [myObject performOperationWithError:&error];
if (!OK) {
// Report the error.
// ...
However, the error declaration is implicitly:NSError * __strong e;
and the method declaration would typically be:-(BOOL)performOperationWithError:(NSError * __autoreleasing *)error;
The compiler therefore rewrites the code:NSError * __strong error;
NSError * __autoreleasing tmp = error;
BOOL OK = [myObject performOperationWithError:&tmp];
error = tmp;
if (!OK) {
// Report the error.
// ...
The mismatch between the local variable declaration (__strong
) and the parameter (__autoreleasing
) causes the compiler to create the temporary variable. You can get the original pointer by declaring the parameterid __strong *
when you take the address of a__strong
variable. Alternatively you can declare the variable as__autoreleasing
. - You cannot give an accessor a name that begins with
new
. This in turn means that you can’t, for example, declare a property whose name begins with new unless you specify a different getter:// Won't work:
@property NSString *newTitle;
// Works:
@property (getter=theNewTitle) NSString *newTitle;
Use Lifetime Qualifiers to Avoid Strong Reference Cycles
You can use lifetime qualifiers to avoid strong reference cycles. For example, typically if you have a graph of objects arranged in a parent-child hierarchy and parents need to refer to their children and vice versa, then you make the parent-to-child relationship strong and the child-to-parent relationship weak. Other situations may be more subtle, particularly when they involve block objects.In manual reference counting mode,__block id x;
has the effect of not retainingx
. In ARC mode,__block id x;
defaults to retainingx
(just like all other values). To get the manual reference counting mode behavior under ARC, you could use__unsafe_unretained __block id x;
. As the name__unsafe_unretained
implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use__weak
(if you don’t need to support iOS 4 or OS X v10.6), or set the__block
value tonil
to break the retain cycle.The following code fragment illustrates this issue using a pattern that is sometimes used in manual reference counting.MyViewController *myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:myController animated:YES completion:^{
[myController release];
}];
As described, instead, you can use a__block
qualifier and set themyController
variable tonil
in the completion handler:MyViewController * __block myController = [[MyViewController alloc] init…];
// ...
myController.completionHandler = ^(NSInteger result) {
[myController dismissViewControllerAnimated:YES completion:nil];
myController = nil;
};
Alternatively, you can use a temporary__weak
variable. The following example illustrates a simple implementation:MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyViewController = myController;
myController.completionHandler = ^(NSInteger result) {
[weakMyViewController dismissViewControllerAnimated:YES completion:nil];
};
For non-trivial cycles, however, you should use:MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler = ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
// ...
[strongMyController dismissViewControllerAnimated:YES completion:nil];
// ...
}
else {
// Probably nothing...
}
};
In some cases you can use__unsafe_unretained
if the class isn’t__weak
compatible. This can, however, become impractical for nontrivial cycles because it can be hard or impossible to validate that the__unsafe_unretained
pointer is still valid and still points to the same object in question.
strong 用来修饰强引用的属性
@property (strong) SomeClass * aObject; 对应原来的
@property (retain) SomeClass * aObject; 和 @property (copy) SomeClass * aObject;
weak 用来修饰弱引用的属性
@property (weak) SomeClass * aObject;
对应原来的
@property (assign) SomeClass * aObject;
__weak, __strong 用来修饰变量,此外还有 __unsafe_unretained, __autoreleasing 都是用来修饰变量的。
__strong 是缺省的关键词。
__weak 声明了一个可以自动 nil 化的弱引用。
__unsafe_unretained 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
__autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。
没有评论:
发表评论