Szukałem przez ostatnie kilka godzin, czytając dziesiątki postów na temat zarządzania pamięcią w celu C i po prostu nie rozumiem. Przepraszam. Robię co w mojej mocy!
W tej chwili szukam odpowiedzi na pytanie, jak zwrócić obiekt z metody, która wywołuje „executeFetchRequest”.
Oto kod ...
+ (Player *)loadPlayerWithPredicate:(NSString *)name:(NSInteger)index
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Player" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// Set filter predicate
NSString *strFilter = [NSString stringWithFormat:@"%@ = %d", name, index];
[request setPredicate:[NSPredicate predicateWithFormat:strFilter]];
// Create the sort descriptors array
NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:name ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sorter]];
NSError *error = nil;
Player *player = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
if ([array count] == 1)
{
player = [array objectAtIndex:0];
//[player retain]; // ???
}
[request release];
return player;
}
Ale to, czego naprawdę potrzebuję, to aby obiekt „player” pozostał w pobliżu po powrocie metody.
Jak mogę ożywić „gracza” po powrocie?
Czy powinienem nazywać „zatrzymaj”? (a potem nazwałbym „zwolnij” w słuchawce) Czy powinienem „skopiować” obiekt?
Przeczytałem wszystkie inne posty dotyczące przydzielania, kopiowania, nowych itp.
Potrzebuję tylko prostego przykładu, abym mógł z niego zrozumieć. Jeśli możesz mi również pokazać przykład odbiornika wywołującego tę metodę, byłbym wdzięczny.
Dzięki!
Odpowiedzi:
1 dla odpowiedzi № 1Możesz użyć kopii, ale wymagałoby to rozszerzenia Player
klasa jest zgodna z NSCopying
protokołu, w co wątpię.
Najprostszy (i prawdopodobnie najlepszy) sposób na zrobienie tego tutaj jest następujący:
if ([array count] == 1)
{
player = [[array objectAtIndex:0] retain];
}
[request release];
return [player autorelease];
W międzyczasie powstrzymujesz odtwarzacz przed zwolnieniem, zatrzymując go, a gdy zwracasz, używasz autorelease
. Nie jest to bezwzględnie konieczne, ale myślę, że w tym przypadku jest to dobra praktyka programistyczna. To dlatego, że twój
+ (Player *)loadPlayerWithPredicate:(NSString *)name:(NSInteger)index;
nazwa funkcji oznaczałaby (w standardowej praktyce Obj-C), że zwrócony obiekt jest automatycznie wydany, pozostawiając w ten sposób zarządzanie pamięcią obiektu wywołującemu.
W klasie, do której dzwonisz + (Player *)loadPlayerWithPredicate:(NSString *)name:(NSInteger)index
, musisz zdecydować, czy chceszzachować zwrócony Player (na przykład ustawić go na właściwość retain) lub jeśli chcesz go pozostawić bez zmian (autoreleased, a zatem prawdopodobnie zostanie zwolniony po zakończeniu metody, w której jest to wywołanie). Użyj tego, jeśli potrzebujesz tylko wykonaj kilka czynności z nim natychmiast i nie musisz go później trzymać).