當物件參考計數歸零,系統自動呼叫 dealloc 釋放記憶體。標準實作模式:
- (void)dealloc {
// 1. 釋放自有實例變數
[_cpu release];
// 2. 呼叫父類別 dealloc
[super dealloc];
}
子類別繼承父類別的實例變數,必須由父類別負責釋放,確保完整清理繼承鏈上的所有資源。
與初始化順序(先父後子)相反,釋放時先清理子類別資源,再呼叫 [super dealloc] 讓父類別釋放其資源。
// Vehicle.h
#import <Foundation/Foundation.h>
@interface Vehicle : NSObject {
NSString *_name;
}
- (id)initWithName:(NSString *)name;
@end
// Vehicle.m
#import "Vehicle.h"
@implementation Vehicle
- (id)initWithName:(NSString *)name {
self = [super init];
if (self) _name = [name copy];
return self;
}
- (void)dealloc {
NSLog(@"vehicle dead");
[_name release];
[super dealloc];
}
@end
// Car.h
#import <Foundation/Foundation.h>
#import "Vehicle.h"
@class Engine;
@interface Car : Vehicle {
Engine *_engine;
}
- (void)setEngine:(Engine *)engine;
@end
// Car.m
#import "Car.h"
#import "Engine.h"
@implementation Car
- (void)setEngine:(Engine *)engine {
if (_engine != engine) {
[_engine release];
_engine = [engine retain];
}
}
- (void)dealloc {
NSLog(@"Car dead");
[_engine release];
[super dealloc];
}
@end
// main.m
#import <Foundation/Foundation.h>
#import "Engine.h"
#import "Car.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *name = [[NSString alloc] initWithFormat:@"audi"];
Car *car = [[Car alloc] initWithName:name];
[name release];
Engine *v6 = [[Engine alloc] init];
[car setEngine:v6];
[v6 release];
[car release]; // 觸發 dealloc 鏈
}
return 0;
}

輸出順序為 Car dead → vehicle dead,驗證釋放順序正確。