2010-12-19 4 views
1

Ja, ich weiß, ich sollte mehr über Speicherverwaltung lesen, habe versucht zu finden und zu verstehen, aber ich verstehe immer noch nicht wirklich, warum dieses Bit des Codes abstürzen, wenn ich die NSMutableArray (siehe Code). Ich mache zunächst/init.Speicherverwaltung nur neugierig

- (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]; 

}

Die '//' zwischen den Zeilen ist nur den Code besser hier formatiert zu bekommen.

Antwort

0

Sie alloc Speicher für Ihre readyPlayers Variable, aber dann zeigen Sie es auf einem anderen Speichersegment:

readyPlayers = [shufflePlayersFunction shufflePlayers: activePlayersArray]; 

readPlayer jetzt Autoreleased ist. Sie haben den Zugriff auf Ihren zuvor zugewiesenen Speicher verloren.

Was Sie tun müssen, ist in erster Linie:

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

und später ... sicher sein, dass wieder freizugeben, wenn nicht gleich Null, wenn Sie fertig sind.

Aber ... Versuchen Sie nicht, dies zu tun !!! Dafür haben Sie Eigenschaften. Machen Sie eine Instanzvariable readyplayer, deklarieren Sie eine Eigenschaft und verwenden Sie synthesize. Jetzt die alloc ändern:

[self setReadyPlayers: [NSMutableArray array]]; 

stellen Sie die readplayer von:

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

Kein Grund zur Sorge über Ihre Array in dealloc usw. Freigabe lassen Sie die os für Sie die fehleranfällige Arbeit zu tun. Wenn readyPlayers wirklich nur eine temporäre Variable ist, vergiss das Alloc und das Release und lass es von der Autorelease verarbeiten.

[shufflePlayersFunction shufflePlayers: activePlayersArray] 

sollte ein automatisch freigegebenes Array zurückgeben.

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

ein großes Dankeschön, wirklich geschätzt. – PeterK

1

Sie müssen nicht zuweisen/init readyPlayers Variable, weil Sie es von shufflePlayers Methode erhalten werden. Die readyPlayers, die von shufflePlayers zurückgegeben wird, sollte auch bereits automatisch freigegeben sein, so dass Sie sie nicht freigeben müssen.

0

Warum ordnen Sie eine Instanz NSMutableArray zu und setzen sie dann auf NSArray? Wenn Sie

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

tun erstellen Sie eine NSMutableArray mit einer Kapazität von 0 und speichern sie auf einen Zeiger theObjects genannt. Später haben Sie:

theObjects = [playerDict valueForKey:myKey]; 

, die den Zeiger setzt Sie früher [playerDict valueForKey:myKey] erstellt. Auf diese Weise verlieren Sie den ursprünglichen Zeiger auf die zugeordnete NSMutableArray. Wenn Sie release an theObjects senden, haben Sie keinen Zugriff mehr auf die ursprünglich erstellte NSMutableArray!

Ich bin nicht sicher, was Sie hier zu erreichen versuchen, aber ich tun würde:

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... 

Das Gleiche gilt für die readyPlayers Array wahr ist, wie tia hingewiesen.

+0

danke euch beiden :-) – PeterK