Object ownership
The ownership of objects can be held in the following ways:
1. Initialization method
- NSString parameter
- (id)initWithName:(NSString *)name { self = [super init]; if (self) { _name = [name copy]; // Set object ownership } return self; }
- Other parameters
- (id)initWithName:(id)name { self = [super init]; if (self) { _name = [name retain]; // Set object ownership } return self; }
2. Setting method
- Direct assignment
- (void)setCPU:(CPU *)cpu { _cpu = cpu; }
- Keep the object directly, release the object in dealloc
- (void)setCPU:(CPU *)cpu { _cpu = [cpu retain]; }
- Release old objects, keep new objects, release objects in dealloc
- (void)setCPU:(CPU *)cpu { if (_cpu != cpu) { [cpu release]; _cpu = [cpu retain]; } }
dealloc definition
The dealloc method is used to automatically call the dealloc method to reclaim memory when the reference count of an object is 0. Its general writing method is:
- (void)dealloc { [super dealloc]; } //or - (void)dealloc { [_obj release]; [super dealloc]; }
- The dealloc method of the parent class is called because some instances of the child class are inherited from the parent class, so it is necessary to inherit the dealloc method of the parent class to release these objects owned by the parent class.
- Call order: generally, when the object of a subclass is released, the instance owned by the parent class is released. This is the opposite of calling [super init] of the initialization method.
Example
1. Example description
- There is a Vehicle
- Create a Car class and inherit Vehicle
- Car owned Engine
2. Code - Create Vehicle.h
#import <Foundation/Foundation.h> @interface Vehicle : NSObject { NSString *_name; } - (id)initWithName:(NSString *)name; @end
- Create Vehicle.m
#import "Vehicle.h" @implementation Vehicle // Initialize vehicle name - (id)initWithName:(NSString *)name { self = [super init]; if (self) { _name = [name copy]; // Set object ownership } return self; } // Override dealloc method - (void)dealloc { NSLog(@"Vehicle dealloc"); [_name release]; // Release the current name [super dealloc]; // Call parent method } @end
- Create Car.h
#import "Vehicle.h" @class Engine; @interface Car : Vehicle { Engine *_engine; // Create engine object } - (void)setEngine: (Engine *)engine; @end
- Create Car.m
#import "Car.h" #import "Engine.h" @implementation Car // Create settings engine method - (void)setEngine: (Engine *)engine { if (_engine!=engine) { // Set object ownership to avoid duplicate objects [_engine release]; // Release old object ownership _engine = [engine retain]; // Keep new object ownership } } // Override dealloc method -(void)dealloc { NSLog(@"Car dealloc"); [_engine release]; // Release engine [super dealloc]; } @end
- Create Engine.h
#import "Vehicle.h" @interface Engine : Vehicle @end
- Create Engine.m
#import "Engine.h" @implementation Engine @end
- Call in main method
#import <Foundation/Foundation.h> #import "Vehicle.h" #import "Car.h" #import "Engine.h" int main(int argc, const char * argv[]) { @autoreleasepool { NSString *name = [NSString stringWithFormat:@"BMW"]; Car *car = [[Car alloc] initWithName: name];// The object ownership of name is given to the Car class [name release];// Release name's own reference count Engine *engine = [[Engine alloc] init]; [car setEngine:engine]; // Engine's reference count + 1, the ownership of engine's object is given to Car class, which is responsible for releasing [engine release];// Release engine's own reference count NSLog(@"Car Reference count for%ld",[car retainCount]);// Reference count is 1 [car release];// When releasing, if the reference count is 0, the dealloc method of Car will be called, then the held engine object will be released, and then the dealloc method of the parent class Vehicle will be called, and the name object will be released } return 0; }