ios developer tiny share-20160913

来源:互联网 发布:c语言product函数 编辑:程序博客网 时间:2024/06/09 19:52

今天讲下Objective-C使用弱引用的场景,以及注意的要点。

Use Strong and Weak Declarations to Manage Ownership
By default, object properties declared like this:

@property id delegate;

use strong references for their synthesized instance variables. To declare a weak reference, add an attribute to the property, like this:

@property (weak) id delegate;

Note: The opposite to weak is strong. There’s no need to specify the strong attribute explicitly, because it is the default.
Local variables (and non-property instance variables) also maintain strong references to objects by default. This means that the following code will work exactly as you expect:

NSDate *originalDate = self.lastModificationDate;self.lastModificationDate = [NSDate date];NSLog(@"Last modification date changed from %@ to %@",originalDate, self.lastModificationDate);

In this example, the local variable originalDate maintains a strong reference to the initial lastModificationDate object. When the lastModificationDate property is changed, the property no longer keeps a strong reference to the original date, but that date is still kept alive by the originalDate strong variable.

Note: A variable maintains a strong reference to an object only as long as that variable is in scope, or until it is reassigned to another object or nil.
If you don’t want a variable to maintain a strong reference, you can declare it as __weak, like this:

NSObject * __weak weakVariable;
Because a weak reference doesn’t keep an object alive, it’s possible for the referenced object to be deallocated while the reference is still in use. To avoid a dangerous dangling pointer to the memory originally occupied by the now deallocated object, a weak reference is automatically set to nil when its object is deallocated.


This means that if you use a weak variable in the previous date example:

NSDate * __weak originalDate = self.lastModificationDate;self.lastModificationDate = [NSDate date];

the originalDate variable may potentially be set to nil. When self.lastModificationDate is reassigned, the property no longer maintains a strong reference to the original date. If there are no other strong references to it, the original date will be deallocated and originalDate set to nil.

Weak variables can be a source of confusion, particularly in code like this:
NSObject * __weak someObject = [[NSObject alloc] init];

In this example, the newly allocated object has no strong references to it, so it is immediately deallocated and someObject is set to nil.

Note: The opposite to __weak is __strong. Again, you don’t need to specify __strong explicitly, because it is the default.
It’s also important to consider the implications of a method that needs to access a weak property several times, like this:

- (void)someMethod {    [self.weakProperty doSomething];    ...    [self.weakProperty doSomethingElse];}

In situations like this, you might want to cache the weak property in a strong variable to ensure that it is kept in memory as long as you need to use it:

- (void)someMethod {    NSObject *cachedObject = self.weakProperty;    [cachedObject doSomething];    ...    [cachedObject doSomethingElse];}

In this example, the cachedObject variable maintains a strong reference to the original weak property value so that it can’t be deallocated as long as cachedObject is still in scope (and hasn’t been reassigned another value).

It’s particularly important to keep this in mind if you need to make sure a weak property is not nil before using it. It’s not enough just to test it, like this:

if (self.someWeakProperty) {[someObject doSomethingImportantWith:self.someWeakProperty];}

because in a multi-threaded application, the property may be deallocated between the test and the method call, rendering the test useless. Instead, you need to declare a strong local variable to cache the value, like this:

NSObject *cachedObject = self.someWeakProperty;           // 1if (cachedObject) {                                       // 2[someObject doSomethingImportantWith:cachedObject];   // 3}                                                         // 4cachedObject = nil;                                       // 5

In this example, the strong reference is created in line 1, meaning that the object is guaranteed to be alive for the test and method call. In line 5, cachedObject is set to nil, thereby giving up the strong reference. If the original object has no other strong references to it at this point, it will be deallocated and someWeakProperty will be set to nil.


0 0
原创粉丝点击