2010-12-19 23 views
1

是的,我知道我應該閱讀更多關於內存管理,試圖找到和理解,但我仍然沒有真正知道爲什麼當我釋放NSMutableArray(見代碼)這段代碼崩潰。我最初做了alloc/init。內存管理只是好奇

- (void)readSelectedPlayers { 
//Prepare File Manager 
NSString *filePath = [self dataFilePath]; 
NSFileManager *fileMgr; 
fileMgr = [NSFileManager defaultManager]; 
// 
NSMutableArray *theObjects = [[NSMutableArray alloc] initWithCapacity:0]; 
NSMutableArray *activePlayersArray = [[NSMutableArray alloc] initWithCapacity:0]; 
NSMutableArray *readyPlayers = [[NSMutableArray alloc] initWithCapacity:0]; 
// 
// Select all keys from the plist 
NSMutableDictionary *playerDict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath]; 
NSArray *allMyKeys = [playerDict allKeys]; 
// 
for(NSString * myKey in allMyKeys) { 
    theObjects = [playerDict valueForKey:myKey]; 

    if ([[theObjects objectAtIndex:1] intValue] == YES) { 
     [activePlayersArray addObject:myKey]; 
    } 
} 
NSLog(@"activePlayersArray: %@", activePlayersArray); 
// 
//========CALL AccesQuestionDB MODULE TO SHUFFLE PLAYERS=========// 
AccessQuestionsDB *shufflePlayersFunction = [AccessQuestionsDB new]; 
readyPlayers = [shufflePlayersFunction shufflePlayers: activePlayersArray]; 
NSLog(@"readyPlayers: %@", readyPlayers); 
// 
[readyPlayers release]; 
[theObjects release]; 
[activePlayersArray release]; 

}

的 '//' 字裏行間只是爲了獲得更好的在這裏格式的代碼。

回答

0

您分配存儲器的readyPlayers變量,但你把它指向的內存一些其他段:

readyPlayers = [shufflePlayersFunction shufflePlayers: activePlayersArray]; 

readPlayer現在會被自動釋放。你失去了以前分配的內存的句柄。

你需要做的主要是:

if (readplayer!= nil){ 
    [readplayer release]; 
} 
readplayer = [[shufflePlayersFunction shufflePlayers: activePlayersArray] retain]; 

後來......可以肯定,當你做如果不是零再次釋放。

但是...不要嘗試這樣做! 這就是你有屬性。爲readyplayer創建一個實例變量,爲它聲明一個屬性並使用合成。現在改變ALLOC到:

[self setReadyPlayers: [NSMutableArray array]]; 

設置readplayer通過:

[self setReadyPlayers: [shufflePlayersFunction shufflePlayers: activePlayersArray]]; 

無需擔心釋放你的數組中的dealloc等讓操作系統做錯誤傾向爲你工作。 如果readyPlayers真的只是一個臨時變量,忘記alloc和release,讓autorelease處理它。

​​3210

應該返回一個自動釋放數組。

NSMutableArray *readyPlayers = [shufflePlayersFunction shufflePlayers: activePlayersArray]; 
NSLog(@"%@", readyPlayers); 
// now forget about it 
+0

一個大謝謝你,真的很感激。 – PeterK 2010-12-19 14:46:53

1

您不需要分配/ init readyPlayers變量,因爲您會從shufflePlayers方法中獲得它。從shufflePlayers返回的readyPlayers也應該已經自動發佈,因此您不必釋放它。

0

你爲什麼要分配一個實例NSMutableArray,然後將其設置爲NSArray?當你做

NSMutableArray *theObjects = [[NSMutableArray alloc] initWithCapacity:0]; 

你爲0的容量創建一個NSMutableArray並將其存儲到一個名爲theObjects指針。稍後您可以:

theObjects = [playerDict valueForKey:myKey]; 

它將您之前創建的指針設置爲[playerDict valueForKey:myKey]。這樣,你就失去了原來指向分配的NSMutableArray的指針。當您將release發送至theObjects時,您無法再訪問最初創建的NSMutableArray了!

我不知道你正試圖在這裏實現的目標,但我會做到:

NSArray *theObjects; 
// some code 
for(NSString * myKey in allMyKeys) { 
    theObjects = [playerDict valueForKey:myKey]; 
    // some more code 
} 
// don't release "theObjects". It's just a pointer... 

同樣適用於readyPlayers陣列真的如TIA指出。

+0

謝謝你們兩位:-) – PeterK 2010-12-19 13:05:31