這是一個很有趣的問題,在Car2復制時候,CAR2的引擎復制了幾次?為什麼?
這個問題涉及到深淺復制,屬性的應用,以及內存的整理等多方面。結果很有趣,答案是三次。
#import#import "Car.h" int main(int argc, const char * argv[]) { @autoreleasepool { Car *car = [[[Car alloc] init] autorelease]; NSLog(@"%@", car); Car *car2 = [car copy]; [car2 release]; } return 0; }
#import#import "Engine.h" #import "Wheel.h" @interface Car : NSObject @property (nonatomic, retain) NSString* name; @property (nonatomic, retain) NSString* brand; @property (nonatomic, copy) Engine *myengine; @property (nonatomic, copy) Wheel *mywheel; @end
#import "Car.h" @implementation Car -(id)copyWithZone:(NSZone*) zone { // 深復制 Car *car1 = [[[self class] allocWithZone:zone] init]; car1.name = [[_name copy] autorelease]; car1.brand = [[_brand copy] autorelease]; car1.myengine = [[_myengine copy] autorelease]; car1.mywheel = [[_mywheel copy] autorelease]; return car1; } - (id)init { if (self = [super init]) { self.brand = @"奔馳"; self.name = @"GLK300"; // 這些值賦予屬性的時候是通過copy的方式,故Wheel要通過alloc ->init -> copy 才能到達Car 的屬性 self.mywheel = [[[Wheel alloc] init] autorelease]; self.myengine = [[[Engine alloc] init] autorelease]; } return self; } - (NSString*)description { NSString* str = [NSString stringWithFormat:@"我是%@,我的名字是%@,我的引擎是%@,我的輪胎是%@", _brand , _name , _myengine , _mywheel]; return str; } - (void)dealloc { // 屬性是指針變量,需要釋放 [_mywheel release]; [_myengine release]; // 在定義中retain 可以釋放 [_name release]; [_brand release]; [super dealloc]; } @end
#import@interface Engine : NSObject @property (nonatomic,copy) NSString* brand; @end
#import "Engine.h" @implementation Engine -(id)copyWithZone:(NSZone *)zone { // 淺復制 Engine *eng = [[[self class] allocWithZone:zone] init]; eng.brand = _brand; NSLog(@"%@馬達加上了!", _brand); return eng; } -(id)init { self = [super init]; self.brand = @"V12"; return self; } -(NSString*)description { return [NSString stringWithFormat:@"%@", _brand]; } @end
#import@interface Wheel : NSObject @property (nonatomic,copy) NSString* brand; @end
#import "Wheel.h" @implementation Wheel -(id)copyWithZone:(NSZone *)zone { // 淺復制 Wheel *wheel2 = [[[self class] allocWithZone:zone] init] ; wheel2.brand = _brand; NSLog(@"%@輪胎加好了!", _brand); return wheel2; } -(id)init { self = [super init]; self.brand = @"馬牌"; return self; } -(NSString*)description { return [NSString stringWithFormat:@"%@", _brand]; } @end