1. 程式人生 > >IOS基礎:retain,copy,assign及autorelease

IOS基礎:retain,copy,assign及autorelease

if (property != newValue) {   
    [property release];   
    property = [newValue retain];   
}

二,深入理解一下(包括autorelease)

1. retain之後count加一。alloc之後count就是1,release就會呼叫dealloc銷燬這個物件。
如果 retain,需要release兩次。通常在method中把引數賦給成員變數時需要retain。
例如:
ClassA有 setName這個方法:
-(void)setName:(ClassName *) inputName
{
   name = inputName;
   [name retain]; //此處retian,等同於[inputName retain],count等於2
}
呼叫時:
ClassName *myName = [[ClassName alloc] init];
[classA setName:myName]; //retain count == 2
[myName release]; //retain count==1,在ClassA的dealloc中release name才能真正釋放記憶體。

2. autorelease 更加tricky,而且很容易被它的名字迷惑。我在這裡要強調一下:autorelease不是garbage collection,完全不同於Java或者.Net中的GC。
autorelease和作用域沒有任何關係!

autorelease 原理:
a.先建立一個autorelease pool
b.物件從這個autorelease pool裡面生成。
c.物件生成 之後呼叫autorelease函式,這個函式的作用僅僅是在autorelease pool中做個標記,讓pool記得將來release一下這個物件。
d.程式結束時,pool本身也需要rerlease, 此時pool會把每一個標記為autorelease的物件release一次。如果某個物件此時retain count大於1,這個物件還是沒有被銷燬。
上面這個例子應該這樣寫:
ClassName *myName = [[[ClassName alloc] init] autorelease];//標記為autorelease
[classA setName:myName]; //retain count == 2
[myName release]; //retain count==1,注意,在ClassA的dealloc中不能release name,否則release pool時會release這個retain count為0的物件,這是不對的。

記住一點:如果這個物件是你alloc或者new出來的,你就需要呼叫release。如果使用autorelease,那麼僅在發生過retain的時候release一次(讓retain count始終為1)。