Memory Management of Instance Variables (ARC)
2013-11-07 23:32
357 查看
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 in
Example 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. So
Example 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 in
Example 12-8; you can still say copy under ARC, and ARC understands how to manage the memory of an object returned from a method whose
camelCased 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;
}
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 in
Example 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. So
Example 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 in
Example 12-8; you can still say copy under ARC, and ARC understands how to manage the memory of an object returned from a method whose
camelCased 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;
}
相关文章推荐
- Memory Management of Instance Variables (Non-ARC)
- Memory Management of Global Variables
- HUNTING YOUR LEAKS: MEMORY MANAGEMENT IN ANDROID (PART 2 OF 2)
- iTron3学习笔记(一) System Calls of Memory Pool Management Functions
- The effective memory management of C++
- Memory Management Guide(matlab编程时经常遇到out of memory 如何解决?)
- 54.Automatic Shared Memory Management (ASMM) has been enabled for your database instance. The initia
- 转自mathworks,matlab Memory Management Guide,解决out of memory
- android Memory Management, OutOfMemoryError Note
- C#Memory Management for Unity Developers(Part 1 of 3)
- Memory Management of primary
- 57.Automatic Shared Memory Management is disabled for your database instance. You realize that there
- Automatic Tuning of Memory Management
- C#Memory Management for Unity Developers (part 2 of 3)
- Wrangling Dalvik: Memory Management in Android (Part 1 of 2)
- Ownership of Memory Management
- Summary of Memory Management Methods
- C# Memory Management for Unity Developers (part 3 of 3)
- Summary of Manual Memory Management Rules