2012-06-01 47 views
1

在目標c中,假設我有一個存儲在NSMutableArray中的對象Obj,並且數組的指針指向整個程序中唯一指向Obj的強指針。現在假設我在Obj上調用方法,並在另一個線程中運行此方法。在這種方法中,如果Obj將自己的指針設置爲等於nil,它是否會從本質上刪除它? (因爲沒有更強的指針了)我懷疑答案是否定的,但爲什麼?如果這確實起作用,那麼它是不是很好的編碼練習(我認爲它不是很好的編碼,但是它實際上很糟糕嗎?)在目標c中,類本質上可以自己刪除嗎?

+2

將'self'設置爲'nil'不會刪除任何內容。 – Dani

+0

沒有將self設置爲零,但將數組中的指針設置爲指向self,等於無 – Nosrettap

+0

您是指類的實例,而不是類本身?如果是的話,你應該編輯這個問題! – Felix

回答

5

如果你的代碼設計正確,那麼一個對象就不太可能導致它自己的釋放/釋放。所以,是的,你所描述的情況表明了錯誤的編碼習慣,事實上可能導致程序崩潰。下面是一個例子:

@interface Widget : NSObject 
@property (retain) NSMutableArray *array; 
@end 

@implementation Widget 

@synthesize array; 

- (id)init 
{ 
    self = [super init]; 
    if(self) { 
     array = [[NSMutableArray alloc] init]; 
     [array addObject:self]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    NSLog(@"Deallocating!"); 
    [array release]; 
    [super dealloc]; 
} 

- (void)removeSelf 
{ 
    NSLog(@"%d", [array count]); 
    [array removeObject:self]; 
    NSLog(@"%d", [array count]); 
} 
@end 

然後這個代碼是在另一個類:

Widget *myWidget = [[Widget alloc] init]; 
[myWidget release]; // WHOOPS! 
[myWidget removeSelf]; 

removeSelf到的NSLog第二呼叫將導致EXC_BAD_ACCESS由於這樣的事實,array已在該被釋放點,不能有方法調用它。

這裏至少有一些錯誤。最終導致崩潰的是一個事實,無論創建和使用對象的類是否在完成使用之前釋放它(調用removeSelf)。沒有這個錯誤,代碼將運行良好。但是,MyWidget不應該有一個實例變量,它首先創建一個強引用自身,因爲這會創建一個保留循環。如果有人試圖在沒有首先調用removeSelf的情況下釋放myWidget,則不會釋放任何內容,並且可能會發生內存泄漏。

0

如果你的反向指針很弱(應該是因爲一個類永遠不應該擁有它所有者,您將最終得到一個保留週期),並且從陣列中刪除強指針,該對象將從堆中移除。沒有強大的指針=從內存中刪除。

你可以隨時測試這個。

0

如果您需要一個班級來處理被刪除的情況,最好的做法是首先保留/自動釋放它,然後使情況發生。在這種情況下,課程不會在其方法中間被刪除,但僅在此之後。

0

我想我們可以這麼說可能是不好的編碼習慣,這取決於你是怎麼做的。你可以安排安全地或可能安全地進行安裝。

因此,讓我們假設我們有一個全球性的:

NSMutableArray *GlobalStore; 

一種方法是刪除自己的最終行動:

- (void) someMethod 
{ 
    ... 
    [GlobalStore removeObject:self]; 
} 

由於這是最後的行動不應該有前途的應用self和所有應該很好,可能...

其他選項包括時間延遲爲0的調度 - 這意味着它將在下一次圍繞r un循環(當然,如果你有一個運行循環,你可能不會這樣做)。這應該總是安全的。

你也可以讓一個對象保持對自身的引用,這會產生一個循環,並保持活動狀態。當它準備好死時,它可以刪除自己的引用,如果沒有其他引用,並且這是最後一個動作(或另一個對象的計劃動作),則該對象已經死亡。

相關問題