How the array object in OC handles reference counting for object elements, and describes the concept of an auto-release pool
how array objects handle reference counting for object elements
[OBJC]View Plaincopy
1.//
2.//MAIN.M
3.//26_nsarraymemerymanager
4.//
5.//Created by Jiangwei on 14-10-12.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import <Foundation/Foundation.h>
10.
#import "Dog.h"
12.
13.
intMain
intargc
Const
Charchar* argv[]) {
14.
15.
Dog*dog1 = [[Dog alloc] init];
16.
Dog*DOG2 = [[Dog alloc] init];
17.
18.
Nsmutablearray*array = [[Nsmutablearray alloc] init];
19.
20.//array will be retain for each element
[Array addobject:dog1]; Dog1 Count =2
[Array addobject:dog2]; Dog2 Count =2
23.
[Dog1 release];
[DOG2 release];
26.
27.//When the array is destroyed, all the elements will be release
[Array release];//arrays destroyed
29.
30.//When the array removes all elements, it will say all the elements release
[Array removeallobjects];
32.
33.
return0;
34.}
We define the dog class and then define the Nsmutablearray array to hold two dog objects, and the Retain method is automatically called when the object is placed in the array, and when the array object itself is destroyed, the release method of all the elements is called. The release method of the element is called when all elements in the array are moved
second, the concept of automatic release pool
[OBJC]View Plaincopy
1.//
2.//MAIN.M
3.//27_autoreleasepool
4.//
5.//Created by Jiangwei on 14-10-13.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import <Foundation/Foundation.h>
10.
#import "Dog.h"
12.
13.
intMain
intargc
Const
Charchar* argv[]) {
14.
15./*
16.//Create an auto-release pool
17.//There is a scope problem, the outside of what is defined in {} is inaccessible, this is different from NSAutoreleasePool
@autoreleasepool {//equivalent to [[NSAutoreleasePool alloc] init]
19.
Dog *DOG2 = [[Dog alloc] init];
[Dog2 retain];
22.
23.}//equivalent to [pool release]
24.
25.//Create an auto-release pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
27.
*dog1 dog = [[Dog alloc] init];//count: 1
29.
30.//Add the Dog1 object to the auto-release pool, but not the previous release method
31.//Join to the auto-release pool, it doesn't mean we don't need to manage references, but auto-free pools automatically call the release
32.//When the automatic release pool is destroyed, releasing the pool calls the release once for each object in the pool
[Dog1 Autorelease];
NSLog (@ "Dog1 count:%ld", Dog1.retaincount);
35.
36.//Destroy the auto-release pool
37.//This will call Dog1 's release method and the Dog1 object will be destroyed.
[Pool release];
39. */
40.
41.//Auto-release pool nesting
42.
NSAutoreleasePool*pool1 = [[NSAutoreleasePool alloc] init];
43.
44.//Add our Code
//dog1 put it in the pool1.
46.
Dog*dog1 = [[Dog alloc] init];
[Dog1 Autorelease];
48.
49.//Auto-release pool nesting
50.
NSAutoreleasePool*pool2 = [[NSAutoreleasePool alloc] init];
51.
//dog2 put it in the pool2.
53.
Dog*DOG2 = [[Dog alloc] init];
[Dog2 Autorelease];
55.
//pool2 destroyed the
[Pool2 Autorelease];
58.
//pool1 destroyed it.
[Pool1 release];
61.
32K
63.//The code below is problematic
//[person Setdog:[[dog alloc] init];
65.//Correct wording
//dog *dogs = [[[Dog alloc] init] autorelease];
67.
68.
69.
70.
return0;
71.}
In our previous article, when we defined an object, we created an auto-release pool, and then we wrote our code in the release pool, which is a system-provided reference counting problem that helps us to manage objects. But sometimes the code must be in {...} This will create a scope problem, that is, in the {...} The variables defined in the {...} cannot be used outside. So there's another way in OC: NSAutoreleasePool this class
This automatic release pool enables nesting
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
Write code ...
Pool1 destroyed the
[Pool1 release];
The above code is equivalent to creating an auto-release pool pool1, but in this middle of the code, if you want to join this pool, you must call the Autorelease method:
[Java]View Plaincopy
1.//dog1 put it in the pool1.
2. Dog *DOG1 = [[Dog alloc] init];
3. [Dog1 autorelease];
Moreover, this definition of a pool can also be nested use, directly look at the above example code, so that the automatic release of the pool we can control. There are a lot more places to operate than the system-provided auto-release pool
Here's a direct comparison:
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init];
This line of code is equivalent to the system automatically releasing the pool {
[Pool1 release];
This line of code is equivalent to the system automatically releasing the pool}
Well, that's a good idea.
Summary
This article mainly introduces the reference problems that need to be handled when the array objects manipulate element objects in OC, and we can customize an auto-release pool, which is more convenient and operable than the automatic release pool provided by the system.
a sore question in the reference count in OC: Circular reference. Note
A sore question in the reference count: Circular reference
On the issue of circular references, there is not much explanation here, that is, multiple objects are referenced to each other, forming loops.
Take a look at a specific example:
Reference to each other between the dog class and the person class
Dog.h
[OBJC]View Plaincopy
1.//
2.//Dog.h
3.//29_cyclepointer
4.//
5.//Created by Jiangwei on 14-10-13.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import <Foundation/Foundation.h>
10.
#import "Person.h"
12.
13.
@interfaceDog:nsobject
14.
15.//There is no retain, if you use retain, it will form a circular reference
16.
@property(
nonatomic, Assign,
ReadWrite)
Person*person;
17.
18.-(
void) Dealloc;
19.
20.
@end
DOG.M
[OBJC]View Plaincopy
1.//
2.//DOG.M
3.//29_cyclepointer
4.//
5.//Created by Jiangwei on 14-10-13.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import "Dog.h"
10.
11.
@implementationDog
12.
13.-(
void) dealloc{
//[_person release];
NSLog (@ "dog dealloc");
16. [
SuperDealloc];
17.}
18.
19.
@end
A property in the dog class that has a person type
Person.h
[OBJC] View Plaincopy
1.//
2.//Person.h
3.//29_cyclepointer
4.//
5.//Created by Jiangwei on 14-10-13.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import <Foundation/Foundation.h>
10.
11.
@classDog;
12.
13.
@interfacePerson:nsobject
14.
15.
@property(
nonatomic,
retain,
ReadWrite)
Dog*dog;
16.
17.-(
void) Dealloc;
18.
19.
@end
person.m
[OBJC] View Plaincopy
1.//
2.//PERSON.M
3.//29_cyclepointer
4.//
5.//Created by Jiangwei on 14-10-13.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import "Person.h"
10.
#import "Dog.h"
12.
13.
@implementationPerson
14.
15.-(
void) dealloc{
[_dog release];
NSLog (@ "Person dealloc");
18. [
SuperDealloc];
19.}
20.
21st.
@end
A property with the dog type in the person class
Check the test code.
main.m
[OBJC] View Plaincopy
1.//
2.//MAIN.M
3.//29_cyclepointer
4.//
5.//Created by Jiangwei on 14-10-13.
6.//Copyright (c) Jiangwei 2014. All rights reserved.
7.//
8.
9. #import <Foundation/Foundation.h>
10.
#import "Dog.h"
#import "Person.h"
13.
14.//Circular Reference
15.//is a very troublesome thing, completely by experience
16.
intMain
intargc
Const
Charchar* argv[]) {
17.
18.
Person*p = [[Person alloc] init];
19.
Dog*dog = [[Dog alloc] init];
20.
[P Setdog:dog];//dog Count: 2
22.
[Dog Setperson:p];//person Count: 2
24.
[P release]; Person Count: 1
[Dog Release];//dog Count: 1
27.
28.//Is not released because the Dealloc method is not executed, the release code is not executed, and the dog and person are waiting each other, forming a ring
29.//The solution version is to cut off the connection between them.
In//@property do not use retain, use Assgin
31.
NSLog (@ "is over");
33.
34.
return0;
35.}
We define a person object and a dog object separately, and then reference each other, but when we call their release method, the two objects are not released.
The reason is simple:
Both the person and the dog refer to each other, and when the release method is executed, the reference count is still 1, so the Dealloc method is not called.
The Dealloc method is not executed, and the release code is not executed, and the dog and the person are waiting each other to form a ring.
The solution is to:
Cut off the connection between them.
When defining attributes in a party, do not use retain in the @property, use Assgin
At the same time, the release method is no longer called in the Dealloc method
In the example above, we can see that the assgin is used in the dog class.
SummaryCircular reference is the object of the destruction of the biggest problem encountered in Java, the garbage collector will also encounter such problems, so do not use reference counting method to manage objects, but another way to manage, you can refer to:http://blog.csdn.net/jiangwei0910410003/article/details/40709457
Reference counting of object elements in OC the related concepts of automatically releasing pools