NSManagedObjectContext executeFetchRequest возвращает ошибочные объекты, вызывает EXC_BAD_ACCESS, SIGABRT и т. Д. - PullRequest
3 голосов
/ 12 июля 2011

Полагаю, мне здесь не хватает фундаментального понимания Core Data, но здесь говорится:

У меня есть несколько запросов на выборку в моем приложении для обработки поиска разных вещей. В некоторых случаях код работает нормально, возвращая запрошенные объекты.

В некоторых случаях он возвращает то, что кажется уже освобожденными объектами (например, всего лишь несколько строк кода, которые позже ссылаются на возвращаемый результат, дают EXC_BAD_ACCESS). Поскольку я устанавливаю различные точки останова и записываю операторы в коде и выполняю его, я также получаю случайные SIGABRT или EXC_BAD_ACCESS в других местах кода.

В каждом случае это происходит, когда я ссылаюсь на результат запроса на выборку.

Вот пример одного такого запроса на выборку:

// Who am I?
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *signedInPersonId = [defaults stringForKey:@"signedInPersonId"];

// Return (if any) the Request object with given UUID
RequestStrings *r = [[RequestStrings alloc] init];
NSEntityDescription *description = [NSEntityDescription entityForName:r.table_Request inManagedObjectContext:moc];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(UUID == %@) && (dataOwnerId == %@)", UUID, signedInPersonId];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:description];
[request setPredicate:predicate];
NSError *error = nil;

NSArray *requests = [moc executeFetchRequest:request error:&error];

Request *returnRequest = nil;
if (requests != nil) {        
    if ([requests count] > 0) {
        NSLog(@"getRequestWithId - requests array: %@, first: %@", requests, [requests objectAtIndex:0]);
        returnRequest = [requests objectAtIndex:0];
    }
    else {
        returnRequest = nil;
    }
}

[r release];
[request release];
return returnRequest;

P.S. Вот еще немного информации В некоторых случаях один и тот же код возвратит нужные объекты или выдаст исключение, указывающее, что [NSCFNumber length] является нераспознанным селектором. Не уверен, как одно и то же описание сущности + запрос на выборку могут вернуть массив в одном случае и число в другом.

Ответы [ 3 ]

3 голосов
/ 12 июля 2011

Вы в основном делаете это:

// (1) Create an array of stuff
NSArray *myArray = [NSarray arrayWithObjects:a, b, c, nil];

// (2) Take the first one off
id myObject = [myArray objectAtIndex:0];

// (3) Release everything
[myArray release];

// (4) Return myObject
return myObject;

Вы просто используете CoreData для выполнения шага (1).

Step (1) возвращает массив объектов. Единственное, что сохраняет эти объекты - это массив, в котором они находятся *. Если вы освободите массив (шаг 3), вы освободите все объекты, которые находятся внутри него. Почему вы ожидаете, что myObject все еще существует в шаге (4)?

Попробуйте это:

// Make sure that we keep a retain of returnRequest
returnRequest = [[[requests objectAtIndex:0] retain] autorelease];

* Для педантиков: я сделал предположение, которое упрощает мой ответ. В реальном мире вы не знаете, что сохраняет ваши объекты - это зависит как от фреймворка, так и от вашего кода. Тем не менее, это хорошая практика, чтобы сохранить все, что вы ожидаете, чтобы держать вокруг.

0 голосов
/ 12 июля 2011

@ deanWombourne - хорошие предложения, и я думаю, что вы правы. Оказывается, я действительно зависал от зомби (не использовал свои собственные сеттеры в предыдущем контроллере представления, когда я использовал значения из ранее извлеченного управляемого объекта).

Решение: EXC_BAD_ACCESS всегда стоит отправиться в путешествие по зомби-лейн. Проанализируйте управление памятью.

0 голосов
/ 12 июля 2011

Почему бы вам не выпустить все релизы в конце до возвращения? Это должно исправить вашу проблему, поскольку вы выпускаете вещи сразу после их создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...