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