OC learning --- array object reference counting and the concept of automatic release pool
Today, let's take a look at how array objects in OC handle the reference counting problem of object elements, and introduce the related concepts of Auto Release pool.
I. How does an array object handle the reference counting of object elements?
//// Main. m // 26_NSArrayMemeryManager /// Created by jiangwei on 14-10-12. // Copyright (c) 2014 jiangwei. all rights reserved. // # import
# Import Dog. hint main (int argc, const char * argv []) {Dog * dog1 = [[Dog alloc] init]; Dog * dog2 = [[Dog alloc] init]; NSMutableArray * array = [[NSMutableArray alloc] init]; // The array returns the retain [array addObject: dog1] for each element; // dog1 COUNT = 2 [array addObject: dog2]; // dog2 COUNT = 2 [dog1 release]; [dog2 release]; // when the array is destroyed, all elements are release [array release]; // destroy the array // when the array removes all elements, it will show all elements release [array removeAllObjects]; return 0 ;}
We define the Dog class and then define the NSMutableArray array to store two Dog objects. When the OC puts the objects in the array, the retain method is automatically called. When the array object is destroyed, the release method of all elements is called. When all elements in the array are removed, the release method of the element is called.
Ii. Concept of automatic release pool
//// Main. m // 27_AutoReleasePool // Created by jiangwei on 14-10-13. // Copyright (c) 2014 jiangwei. all rights reserved. // # import
# Import Dog. hint main (int argc, const char * argv []) {/* // create an automatic release pool // has a scope problem, the things defined in {} cannot be accessed outside, @ autoreleasepool, which is different from the NSAID utoreleasepool {// equivalent to [NSAID utoreleasepool alloc] init] Dog * dog2 = [[Dog alloc] init]; [dog2 retain];} /// equivalent to [pool release] // create an automatic release pool named [nutoreleasepool * pool = [[nutoreleasepool alloc] init]; Dog * dog1 = [[Dog alloc] init]; // count: 1 // Add the dog1 object to the Auto release pool, but not after the previous release method is added to the Auto release pool, it does not mean that we do not need to manage references, but the Auto release pool will automatically call a release // when the Auto release pool is destroyed, the release pool calls release [dog1 autorelease]; NSLog (@ dog1 count: % ld, dog1.retainCount) for each object in the pool ); // destroy the automatically released pool // The dog1 release method will be called at this time, and the dog1 object will be destroyed [pool release]; * // automatically release the nested NSAID utoreleasepool * pool1 = [[NSAID utoreleasepool alloc] init]; // Add our code // dog1 to pool1 Dog * dog1 = [[Dog alloc] init]; [dog1 autorelloc]; // automatically release the nested NSAID utoreleasepool * pool2 = [[NSAID utoreleasepool alloc] init]; // put dog2 in pool2 Dog * dog2 = [[Dog alloc] init]; [dog2 autorelease]; // pool2 destroys [pool2 autorelease]; // pool1 destroys [pool1 release]; // the following code is problematic // [person setDog: [[Dog alloc] init]; // correct syntax // Dog * dogs = [[[Dog alloc] init] autorelease]; return 0 ;}
In our previous article, when defining an object, we will generate an automatic release pool, and then write our code in the release pool, the automatic release pool is a kind of help provided by the system to help us manage the reference count of objects. But sometimes the Code must be in {...} in this case, the scope problem will occur, that is, in {...} variables defined in {...} it cannot be used outside. So there is another method in OC: the class of NSAID utoreleasepool.
This automatic release pool can implement nesting
NSAID utoreleasepool * pool1 = [[NSAID utoreleasepool alloc] init];
// Write code...
// Pool1 destroyed
[Pool1 release];
The above code is equivalent to creating an automatic release pool pool1, but the code in the middle must call the autorelease method if you want to join the pool:
// Dog * dog1 = [[Dog alloc] init]; [dog1 autorelease] In pool1;
In addition, a pool can be defined in this way and can be nested. Let's look at the above example code, so that we can control the automatic release pool. It is more operable than the automatic release pool provided by the system.
The following is a direct comparison:
NSAID utoreleasepool * pool1 = [[NSAID utoreleasepool alloc] init];
This line of code is equivalent to {
[Pool1 release];
This line of code is equivalent to automatically releasing the pool}
So I can understand it.
Summary
This article mainly introduces the reference issues that need to be addressed when the array object in OC operates on element objects, and we can customize an automatic release pool, this method is more convenient and operable than the automatic release pool provided by the system.