Memory Management of Instance Variables (ARC)

来源:互联网 发布:c 并发编程实践 pdf 编辑:程序博客网 时间:2024/05/21 00:47

If you’re using ARC, ARC will manage your instance variable memory for you; you needn’t (and, by and large, you can’t) do it for yourself. All this means is that ARC will do, literally but invisibly, exactly the things I just described in the preceding section.

Let’s start with direct assignment to an instance variable. By default, ARC will treat an instance variable the same way it treats any variable: on assignment to that instance variable, it creates a temporary variable, retains the assigned value in it, releases the current value of the instance variable, and performs the assignment. Thus, you write this code:

self->_theData = d;

ARC, in effect, in accordance with its rule that it retains on assignment and releases the old value, substitutes something like this scenario:

// imaginary scenario: retain on assignment, release the previous value

id temp = self->_theData;

self->_theData = d;

[self->_theData retain];

[temp release];

This is exactly the right thing to have happened; in fact, it will not have escaped your attention that it is virtually the same code you would have written for a formal setter such asExample 12-4. So much for worrying about release and retain on assignment!

The same thing is true if we actually write a formal setter. A simple setter is nowhere near as elaborate as a pre-ARC setter; indeed, it might consist of no more than a direct assignment, because ARC is once again doing quite correctly all theattendant manual memory management, in accordance with the scenario I just described:

- (void) setTheData: (NSMutableArray*) value {

    self->_theData = value;

}

Moreover, when your object goes out of existence, ARC releases its retained instance variable values. So much for worrying about releasing in dealloc! You may still need, under ARC, to implement dealloc for other reasons — for example, it could still be the right place to unregister for a notification (Chapter 11) — but you won’t call release on any instance variables there, and you won’t call super. (Under ARC, at the time dealloc is called, your instance variables have not yet been released, so it’s fine to refer to them in dealloc.)


In the absence of a release call, which is forbidden under ARC, what happens if you want to release an instance variable’s value manually? The solution is simple: set the instance variable to nil (possibly by way of the setter). When you nilify a variable, ARC releases its existing value for you by default.



Finally, let’s talk about ARC’s implications for the way you’ll write an initializer that involves setting object instance variable values, as inExample 12-5 and Example 12-6. The code for these initializers will be just the same under ARC as under non-ARC, except that you needn’t (and can’t) say retain. SoExample 12-5 under ARC would look like Example 12-7.

Example 12-7. A simple initializer that retains an ivar under ARC

- (id) initWithName: (NSString*) s {

    self = [super init];

    if (self) {

        self->_name = s;

    }

    return self;

}

Example 12-6 under ARC will be unchanged, as shown inExample 12-8; you can still say copy under ARC, and ARC understands how to manage the memory of an object returned from a method whosecamelCased name starts with (or simply is) copy.

Example 12-8. A simple initializer that copies an ivar under ARC

- (id) initWithName: (NSString*) s {

    self = [super init];

    if (self) {

        self->_name =[s copy];

    }

    return self;

}


原创粉丝点击