1

我有以下的方法,它是通過調用的(使用NSThread)一個新的線程產生:保留在NSThread創建的對象

- (void) updateFMLs { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess]; 

    [self performSelectorOnMainThread:@selector(doneLoading:) withObject:temp waitUntilDone:NO]; 
    [pool release]; 
} 

doneLoading:方法是這樣的:

- (void) doneLoading:(NSArray *)obj { 
    myArray = [[NSArray alloc] initWithArray:obj copyItems:NO]; 
} 

myArray的內容變爲無效。我如何保留myArray的內容,以便稍後在我的應用程序中使用它們?

P.S.在類頭文件中定義了myArray

+0

什麼意思是「變得無效」。他們是否被釋放? – 2009-08-04 02:57:50

+1

順便說一句,你泄漏的「溫度」陣列。你分配一個數組(+1保留計數),但你永遠不會釋放它。 – 2009-08-04 03:02:44

+0

是的,他們似乎成爲釋放,因爲我通過doneLoading進展...即使沒有任何doneLoading,除了上面顯示的行,以任何方式改變myArray – zpesk 2009-08-04 03:05:43

回答

0

您發佈的代碼看起來很好,除了內存泄漏updateFMLs。你可能在其他地方過度釋放對象。我猜測它會在someArrayFromAnotherProcess的任何地方生成。

1

如果你的後臺線程做了一些工作,需要「通行證」的NSArray到你的主線程,那麼所有doneLoading需要做的是:

-(void)doneLoading:(NSArray *)obj 
{ 
    [myArray release]; // release the previous array and its objects 
    myArray = [obj retain]; 
    // now use myArray, refresh tables, etc. 
} 

有(可能)沒有必要作出的另一個副本數組,這可能是潛在的問題。您的performSelector調用後也應該調用[temp release],因爲已經保存了參數。

如果myArray的內容以某種方式變得有效,那麼它們將在某處被雙倍釋放。 myArray將保留添加到它的任何對象。您提到myArray本身已變得無效,因此請嘗試使用此模式重寫您的後臺線程和doneLoading方法。

最後,您應該使用[pool drain]代替[pool release]

0

到選項的替代上面會在頭申報myArray的作爲原子屬性

@property (atomic,retain) NSArray *myArray; 

然後在updateFMLs你應該能夠簡單地從次級線程中調用的setter。顯然這隻有在你願意支付原子屬性的性能損失時纔有效。

- (void) updateFMLs { 
    NSAutoreleasePool *pool - [[NSAutoreleasePool alloc] init]; 
    NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess]; 
    [self setMyArray:temp]; 
    [temp release]; 
    [pool drain]; 
}