OC object memory management MRC manual memory management
- In iOS, reference counting is used to manage the memory of OC objects; basic data types do not require memory management.
- The default reference count of a newly created OC object is 1. When the reference count is reduced to 0, the OC object is destroyed, freeing up its memory
- A call to retain gives the OC object’s reference count +1, and a call to release gives the OC object’s reference count -1
- Summary of experience in memory management
-
Xxx. retainCount // Check the reference count.
-
When the alloc, new, copy, and mutableCopy methods return an object, release or autoRelease is called when the object is no longer needed
-
To own an object, make its reference count +1; If you don’t want to own an object, let its reference count be -1
-
- practice
- Disable automatic reference count management
- Basic manual reference count management
- Because you can’t figure out when it’s good to free the memory autorelease will free it automatically, okay
// MJPerson *person1 = [[[MJPerson alloc] init] autoRelease]; // MJPerson *person2 = [[[MJPerson alloc] init] autorelease]; }Copy the code
- How to use this when classes are related to each other
- Given that person has dog member attributes, how does that dog manage memory
- The source code
- MJPerson.h #import <Foundation/Foundation.h> #import "MJDog.h" @interface MJPerson : NSObject { MJDog *_dog; int _age; } - (void)setAge:(int)age; - (int)age; - (void)setDog:(MJDog *)dog; - (MJDog *)dog; @end - MJPerson.m #import "MJPerson.h" @implementation MJPerson - (void)setAge:(int)age { _age = age; } - (int)age { return _age; } - (void)setDog:(MJDog *)dog { if (_dog ! = dog) { [_dog release]; _dog = [dog retain]; } } - (MJDog *)dog { return _dog; } - (void)dealloc { // [_dog release]; // _dog = nil; self.dog = nil; // Set is called to free memory. NSLog(@"%s", __func__); // Superclass dealloc is placed last [super dealloc]; } @end - MJDog.h #import <Foundation/Foundation.h> @interface MJDog : NSObject - (void)run; @end - MJDog.m #import "MJDog.h" @implementation MJDog - (void)run { NSLog(@"%s", __func__); } - (void)dealloc { [super dealloc]; NSLog(@"%s", __func__); } @end - MJDog.h #import <Foundation/Foundation.h> @interface MJDog : NSObject - (void)run; @end - MJDog.m #import "MJDog.h" @implementation MJDog - (void)run { NSLog(@"%s", __func__); } - (void)dealloc { [super dealloc]; NSLog(@"%s", __func__); } @endCopy the code
- call
void test2()
{
MJDog *dog = [[MJDog alloc] init]; // 1
MJPerson *person1 = [[MJPerson alloc] init];
[person1 setDog:dog]; // 2
MJPerson *person2 = [[MJPerson alloc] init];
[person2 setDog:dog]; // 3
[dog release]; // 2
[person1 release]; // 1
[[person2 dog] run];
[person2 release]; // 0
}
Copy the code
- Replace attribute old release first, new +1.
- Analysis of the
- 1.MJDog *dog = [[MJDog alloc] init]; // 1 The dog class counts 1
- 2.[person1 setDog:dog]; Call -> _dog = [dog retain]; // Dog count +1 = 2
- 3.[person2 setDog:dog]; / / 3
- 4.[dog release]; // 2 corresponds to the first instruction created after -1 =2
- 5.[person1 release]; // 1 [person2 release]; // 0 The person class decrement its own count by one and calls its own dealloc. The reference count of the member variables owned by Person is -1, so dog decrement twice and the reference count becomes 0, freeing memory.
- Optimize the code
- MJPerson.h #import <Foundation/Foundation.h> #import "MJDog.h" @property (nonatomic, assign) int age; // Assign is a direct assignment. @property (nonatomic, retain) MJDog *dog; // The object type is used. When the object is replaced, the value will be automatically determined and then assigned. Free old memory -1, +1 for new memory. Note: Delloc sets member variables to nil. + (instanceType)person; @end - MJPerson.m #import "MJPerson.h" @implementation MJPerson + (instancetype)person { return [[[self alloc] init] autorelease]; } - (void)dealloc { self.dog = nil; self.car = nil; NSLog(@"%s", __func__); [super dealloc]; } @endCopy the code