我不是很明白其中“nsmutablearray类对象被赋值给变量obj,但obj自己并不持有该对象,使用retain可以持有该对象”这句话。
然后我在网上看到这个,应该是对应“非自己生成的对象,自己也能持有”这个情况,然后我写了下面的代码
NSMutableArray *array = [NSMutableArray arrayWithObjects: @"one", @"two", nil];
NSString *elem = array[0];
[array removeAllObjects];
NSLog(@"%@", elem);
既然removeallobjects了就应该被dealloc了,为什么还能打印出elem呢?
还有第二种代码,person被release之后为什么还可以访问name
People *person = [[People alloc] init];
[person release];
NSString *name = person.name;
NSLog(@"%@", name);
這是個引用計數機制的問題,簡單的來說,一個物件透過alloc,copy 之類的初始化的時候,它的retainCount 會變成1,每retain 一次,retainCount 加1,每release 一次,retainCount 減1 ,物件被加到集合(例如array)裡的時候會自動retain 一次,被從集合裡移除時,會自動release。 當物件的 retainCount 變成 0 時,該物件會被標記為 free,原則上來說,這時候就不應該再存取該物件了, 因為它隨時可能會被釋放掉。
「非自己生成的對象,自己也能持有」就是指一個對象雖然不是自己生成的,但是你可以retain 它,這樣它的retainCount 就是加1,如果別的地方沒有過度release 的話,在你release在它之前,它的retainCount 至少是1,這就跟你持有它是一樣的。
你的後面兩個問題在於你的測試程式碼用錯了對象, NSString 不走 retain/release 那一套,你可以把你的測試裡的 NSString 都換成 NSMutableString 或者隨便一個對象 ObjectA 試一試。
最後一個問題 person 被 release 之後 retainCount 應該是 0 了,為什麼還能去 person.name 呢?原因在於 person 指標指向的物件的 retainCount 達到 0 之後並不是會立即被清楚掉,可能需要等到下個 runloop,這時候 person 指標依然是指向著那個對象,而 name 又是個 NSString,所以可以存取。