iOS objective-C retainCount, OC計數器的思考


學OC,肯定知道內存管理機制的原則。這里說說某些特殊的情況。

之前曾說,NSString的計數器比較特殊,大家注意下。

今天說另外一種,也是比較糾結的,以至於朋友都說這是OC BUG。。。

創建一個Class:

//H
#import <Foundation/Foundation.h>

@interface Car : NSObject

- (void)show;

@end

//M
#import "Car.h"

@implementation Car

- (void)show;{
    NSLog(@"exec Finished!!!");
}

@end

很簡單的show方法,確認Car類是否被free;

運行方法:

Car *car = [[Car alloc] init];
[car show];
[car release];
[car show];
NSLog(@"car retainCount:%d", [car retainCount]);

某些人可能一眼看出,執行未完成就會Crash;

但事實是,毫無Crash征兆,並且retainCount printf 1;

為什么會這樣??經過與幾個基友討論,得出以下結論:

1.car堆被標記,即release執行完成,但因為不是立即釋放,所以內存還存在;

2.存在棧中的car指針不由我們控制,同樣未釋放。

所以,給car指針指向的那塊內存發送show消息時,又得到了結果。

既然不是OC的BUG,那如果避免?

在我們的項目中,肯定不會出現這樣的問題,因為當堆被標記,有新創建的OBJ,會自動占用掉。

可以這樣模擬:

Car *car = [[Car alloc] init];
[car show];
[car release];
for (int i = 0; i < 1000; i++) {
    @autoreleasepool {
        NSString *str = [NSString stringWithFormat:@"X%d", i];
        NSLog(@"%@", str);
    }
}
[car show];
NSLog(@"%d", [car retainCount]);

此時,不等運行到顯示car的retainCount,已經Crash;

符合我們的結論;

如何避免就是大家熟悉的,在release后再設置nil即可;

其他的內存方面就不說了,只說奇葩的部分!!不對的地方請指出,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM