2013-05-08 2 views
0

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

Например, (MyManagedObjectEntityClass, а также> идентификатор < заполнители):

MyManagedObjectEntityClass *o = [NSEntityDescription insertNewObjectForEntityForName:@"<MyManagedObjectEntityClass Entity Name>" inManagedObjectContext:self.localContext]; 
    NSLog(@"\n%@", o); 
    [self.localContext deleteObject:o]; 
    NSLog(@"\n%@", o); 

зарегистрирует, что объект все еще существует только то, что это данные неисправности.

И добавление [self.localContext save:nil]; после удаления также не изменяет это.

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

На всякий случай, да, я знаю, что смогу вместо этого проверить o на -isFault. Но дело в том, что экстраполируйте этот тест на NSSet, и я не могу просто полагаться на [[set anyObject] isFault], чтобы сделать вывод о том, что все объекты в этом наборе были удалены (в идеале счетчик набора будет 0, но все объекты по-прежнему существуют как сбои).

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

+0

Вы пробовали тестирование с помощью '[o isDeleted]'? –

+0

Вещь - это то, что ставит меня в ту же лодку, что и isFault. Сами объекты удаляются из контекста. Если я сделаю запрос выборки после удаления, контекст не возвращает совпадений.Проблема в том, что любые ссылки на объекты, хранящиеся в клиентском коде (NSArray в контроллере представления, например, содержащий кучу управляемых объектов) по-прежнему находятся в коллекции после удаления, и хотя они являются ошибками, они все еще являются объектами, если Я тестирую ноль или проверяю счет коллекции. – SaldaVonSchwartz

+0

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

ответ

1

Это не проблема с основными данными. C (и по расширению Objective-C) не работает.

Метод deleteObject: принимает один аргумент, указатель на объект. Он может изменить объект (например, установить его флаг isDeleted), или он может делать другие вещи, связанные с объектом (например, удалять его из контекста управляемого объекта). Он не может изменить значение самого указателя. Итак, что бы он ни делал или не должен делать, C говорит, что когда это будет сделано, указатель, который вы передаете, по-прежнему указывает на то же место в памяти. В результате на самом деле невозможно, чтобы этот метод заставлял этот указатель быть нулевым на этом языке. Если вы хотите, чтобы это было ноль, вы должны сами изменить это. (В стороне, было бы возможно реализовать метод, чтобы взять указатель на аргумент указателя, который мог бы изменить ваш указатель. Это не повлияет на другие ссылки, такие как в массивах, хотя это было бы вроде бессмысленно).

Именно поэтому метод isDeleted является общедоступным, так что если у вас есть указатель на этот объект в другом месте, вы можете проверить, было ли оно удалено, прежде чем пытаться его использовать.

Если это не удобно (и часто это не так), Core Data также предоставляет NSManagedObjectContextObjectsDidChangeNotification и NSManagedObjectContextDidSaveNotification. Вы можете использовать их в любом месте своего приложения, чтобы получать уведомления об изменениях в контексте и отвечать любым способом (например, обновлять массив). Эти уведомления пытаются помочь вам, предоставив списки вставленных, обновленных и удаленных объектов. Используйте их, когда это возможно, чтобы проверить, действительно ли вам нужно обновлять свои ссылки.

+0

Я знаю разницу между семантикой C/obj-C и C++. Но я думаю, я думал об этом с точки зрения типа oldschool C. Что-то в строках 'typedef struct { int num; } obj; int main() { obj * a [3]; a [0] = malloc (sizeof (obj)); a [0] -> num = 55; printf ("\ n% p", a [0]); бесплатно (a [0]); a [0] = NULL; printf ("\ n% p", a [0]); возвращение 0; } '. Благодаря! – SaldaVonSchwartz