更新:一个改进的答案,基于下面讨论中的詹姆斯·哈德斯顿的想法。
- (BOOL)hasManagedObjectBeenDeleted:(NSManagedObject *)managedObject {
NSParameterAssert(managedObject);
NSManagedObjectContext *moc = [self managedObjectContext];
if ([moc respondsToSelector:@selector(existingObjectWithID:error:)])
{
NSManagedObjectID *objectID = [managedObject objectID];
NSManagedObject *managedObjectClone = [moc existingObjectWithID:objectID error:NULL];
if (!managedObjectClone)
return YES;
else
return NO;
}
else if ([moc respondsToSelector:@selector(countForFetchRequest:error:)])
{
if (![managedObject managedObjectContext])
return YES;
NSManagedObjectID *objectID = [managedObject objectID];
NSManagedObject *managedObjectClone = [moc objectWithID:objectID];
NSEntityDescription *entityDescription = [managedObjectClone entity];
NSDictionary *propertiesByName = [entityDescription propertiesByName];
NSArray *propertyNames = [propertiesByName allKeys];
NSAssert1([propertyNames count] != 0, @"Method cannot detect if |managedObject| has been deleted because it has zero Properties defined: %@", managedObject);
@try
{
(void)[managedObjectClone valueForKey:[propertyNames objectAtIndex:0]];
return NO;
}
@catch (NSException *exception)
{
if ([[exception name] isEqualToString:NSObjectInaccessibleException])
return YES;
else
[exception raise];
}
}
else
{
NSAssert(0, @"Unsupported version of Mac OS X detected.");
}
}
旧的/弃用的答案:
我写了一个更好的方法。self
是您的核心数据类/控制器。
- (BOOL)hasManagedObjectBeenDeleted:(NSManagedObject *)managedObject
{
if (![managedObject managedObjectContext])
return YES;
NSManagedObjectID *objectID = [managedObject objectID];
NSManagedObject *managedObjectClone = [[self managedObjectContext] objectWithID:objectID];
NSEntityDescription *entityDescription = [managedObjectClone entity];
NSDictionary *propertiesByName = [entityDescription propertiesByName];
NSArray *propertyNames = [propertiesByName allKeys];
@try
{
for (id propertyName in propertyNames)
(void)[managedObjectClone valueForKey:propertyName];
return NO;
}
@catch (NSException *exception)
{
if ([[exception name] isEqualToString:NSObjectInaccessibleException])
return YES;
else
[exception raise];
}
}
正如詹姆斯·哈德斯顿(James Huddleston)在回答中提到的那样,检查一下NSManagedObject的-managedObjectContext
退货nil
是否是一种“相当不错的”方式,以查看是否已从持久性存储中删除了已缓存/过时的NSManagedObject,但这并不总是如Apple在其文档中所指出的那样准确:
这个方法 如果接收者已从其上下文中删除,则可能返回nil。
什么时候不返回nil?如果您使用已删除的NSManagedObject的商品获得其他NSManagedObject的商品-objectID
如下所示:
CoreData *coreData = ...;
NSManagedObject *apple = [coreData addManagedObject:@"Apple"];
[apple setValue:@"Mcintosh" forKey:@"name"];
[coreData saveMOCToPersistentStore];
NSManagedObjectContext *moc = [apple managedObjectContext];
if (!moc)
NSLog(@"2 - Deleted.");
else
NSLog(@"2 - Not deleted.");
[[coreData managedObjectContext] deleteObject:apple];
moc = [apple managedObjectContext];
if (!moc)
NSLog(@"3 - Deleted.");
else
NSLog(@"3 - Not deleted.");
[coreData saveMOCToPersistentStore];
moc = [apple managedObjectContext];
if (!moc)
NSLog(@"4 - Deleted.");
else
NSLog(@"4 - Not deleted.");
NSManagedObjectID *deletedAppleObjectID = [apple objectID];
NSManagedObject *appleClone = [[coreData managedObjectContext] objectWithID:deletedAppleObjectID];
moc = [appleClone managedObjectContext];
if (!moc)
NSLog(@"5 - Deleted.");
else
NSLog(@"5 - Not deleted.");
BOOL deleted = [coreData hasManagedObjectBeenDeleted:appleClone];
if (deleted)
NSLog(@"6 - Deleted.");
else
NSLog(@"6 - Not deleted.");
这是打印输出:
2 - Not deleted.
3 - Not deleted.
4 - Deleted.
5 - Not deleted.
6 - Deleted.
如您所见,-managedObjectContext
如果从持久性存储中删除了NSManagedObject ,则将不会总是返回nil。
isInserted
我所知,还有一种方法可以在NSManagedObject上返回BOOL。在这种情况下使用它可能会更清洁一些。