为什么[self.individuals allObjects]
返回零?
编辑:
在发现您的managedObjectContext
is之后,可以nil
肯定地说您的对象已被其上下文否认。
这可能是由上下文reset
或释放引起的,而您保持对对象的强引用。
然而,这并不能解释这在prepareForDeletion
方法内部是如何发生的。
当实时上下文正在删除对象 () 时,将调用此方法[context deleteObject:...]
。
这意味着您要么prepareForDeletion
手动调用 ( [object prepareForDeletion]
),要么另一个线程在删除过程中重置/释放您的上下文。
注意:如果您的对象上有一个有效objectID
的活动managedObjectContext
集,则下面的代码将起作用。
但是,我可能有一个解决方法,因为您访问数据的方式有些低效(稍后会解释):
PhoneGroup
如果您的已删除对象individuals
(然后,您将作为该关系中包含的对象(N 个对象)出现故障,您的循环将一一访问它们(N 次前往商店)。仍然在循环中,您可以访问每个对象的关系(2 个关系船,phoneGroups
并且reminders
==> 2 次前往每个项目的商店)。
总之:1 + N + 2*N = 3*N +1 次去商店(最坏的情况)。
这可以通过更简单的方式完成:
* 创建这个获取请求:
NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"Individual"];
[r setPredicate:[NSPredicate predicateWithFormat:@"%@ IN phoneGroups AND phoneGroups.@count == 1 AND reminders.@count == 0",[self objectID]]];
[r setIncludesPropertyValues:YES];
[r setReturnsObjectsAsFaults:NO];
[r setIncludesPendingChanges:YES];
* 现在剩下的就是:
NSManagedObjectContext* context = [self managedObjectContext];
NSArray* individuals = [context executeFetchRequest:r error:NULL];
for (Individual* individual in individuals) {
[context deleteObject:individual];
}
在最坏的情况下,这是通过单 (1) 次前往商店来完成的,并且由于您不直接依赖您的关系,因此只要您的对象具有它的objectID
.
附录:
当前实现性能(SQLite 调试):
//2013-05-19 21:34:42.700 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM Z_2PHONEGROUPS t1 JOIN ZCONTACT t0 ON t0.Z_PK = t1.Z_2INDIVIDUALS WHERE t1.Z_3PHONEGROUPS = ?
//2013-05-19 21:34:42.701 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.701 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 3 rows.
//2013-05-19 21:34:42.715 P[9666:c07] CoreData: annotation: to-many relationship fault "individuals" for objectID 0x8572b70 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/PhoneGroup/p21> fulfilled from database. Got 3 rows
//2013-05-19 21:34:42.716 P[9666:c07] CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZCONTACTID, t0.ZVISIBLE FROM ZCONTACT t0 WHERE t0.Z_PK = ?
//2013-05-19 21:34:42.717 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0005s
//2013-05-19 21:34:42.717 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 1 rows.
//2013-05-19 21:34:42.718 P[9666:c07] CoreData: annotation: fault fulfilled from database for : 0x818cad0 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p4>
//2013-05-19 21:34:42.718 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM Z_2PHONEGROUPS t1 JOIN ZCONTACT t0 ON t0.Z_PK = t1.Z_3PHONEGROUPS WHERE t1.Z_2INDIVIDUALS = ?
//2013-05-19 21:34:42.719 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.719 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 1 rows.
//2013-05-19 21:34:42.719 P[9666:c07] CoreData: annotation: to-many relationship fault "phoneGroups" for objectID 0x818cad0 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p4> fulfilled from database. Got 1 rows
//2013-05-19 21:34:42.720 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM ZREMINDER t0 WHERE t0.ZCONTACT = ?
//2013-05-19 21:34:42.721 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0005s
//2013-05-19 21:34:42.721 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 0 rows.
//2013-05-19 21:34:42.721 P[9666:c07] CoreData: annotation: to-many relationship fault "reminders" for objectID 0x818cad0 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p4> fulfilled from database. Got 0 rows
//2013-05-19 21:34:42.722 P[9666:c07] CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZCONTACTID, t0.ZVISIBLE FROM ZCONTACT t0 WHERE t0.Z_PK = ?
//2013-05-19 21:34:42.722 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.722 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 1 rows.
//2013-05-19 21:34:42.723 P[9666:c07] CoreData: annotation: fault fulfilled from database for : 0x818cb90 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p16>
//2013-05-19 21:34:42.723 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM Z_2PHONEGROUPS t1 JOIN ZCONTACT t0 ON t0.Z_PK = t1.Z_3PHONEGROUPS WHERE t1.Z_2INDIVIDUALS = ?
//2013-05-19 21:34:42.724 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.724 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 1 rows.
//2013-05-19 21:34:42.724 P[9666:c07] CoreData: annotation: to-many relationship fault "phoneGroups" for objectID 0x818cb90 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p16> fulfilled from database. Got 1 rows
//2013-05-19 21:34:42.725 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM ZREMINDER t0 WHERE t0.ZCONTACT = ?
//2013-05-19 21:34:42.725 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.726 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 0 rows.
//2013-05-19 21:34:42.726 P[9666:c07] CoreData: annotation: to-many relationship fault "reminders" for objectID 0x818cb90 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p16> fulfilled from database. Got 0 rows
//2013-05-19 21:34:42.727 P[9666:c07] CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZCONTACTID, t0.ZVISIBLE FROM ZCONTACT t0 WHERE t0.Z_PK = ?
//2013-05-19 21:34:42.727 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.727 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 1 rows.
//2013-05-19 21:34:42.728 P[9666:c07] CoreData: annotation: fault fulfilled from database for : 0x818cba0 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p17>
//2013-05-19 21:34:42.728 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM Z_2PHONEGROUPS t1 JOIN ZCONTACT t0 ON t0.Z_PK = t1.Z_3PHONEGROUPS WHERE t1.Z_2INDIVIDUALS = ?
//2013-05-19 21:34:42.729 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.729 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0008s for 4 rows.
//2013-05-19 21:34:42.729 P[9666:c07] CoreData: annotation: to-many relationship fault "phoneGroups" for objectID 0x818cba0 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p17> fulfilled from database. Got 4 rows
//2013-05-19 21:34:42.730 P[9666:c07] CoreData: sql: SELECT 0, t0.Z_PK FROM ZREMINDER t0 WHERE t0.ZCONTACT = ?
//2013-05-19 21:34:42.730 P[9666:c07] CoreData: annotation: sql connection fetch time: 0.0004s
//2013-05-19 21:34:42.731 P[9666:c07] CoreData: annotation: total fetch execution time: 0.0007s for 0 rows.
//2013-05-19 21:34:42.731 P[9666:c07] CoreData: annotation: to-many relationship fault "reminders" for objectID 0x818cba0 <x-coredata://CBE585F2-552D-4FDE-AAEA-2C9C7984FAC9/Individual/p17> fulfilled from database. Got 0 rows
建议的实施绩效:
//2013-05-19 21:13:26.734 P[9609:c07] CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZCONTACTID, t0.ZVISIBLE FROM ZCONTACT t0 JOIN Z_2PHONEGROUPS t1 ON t0.Z_PK = t1.Z_2INDIVIDUALS WHERE ((t1.Z_3PHONEGROUPS = ? AND (SELECT COUNT(t3.Z_3PHONEGROUPS) FROM Z_2PHONEGROUPS t3 WHERE (t0.Z_PK = t3.Z_2INDIVIDUALS) ) = ? AND (SELECT COUNT(t4.Z_PK) FROM ZREMINDER t4 WHERE (t0.Z_PK = t4.ZCONTACT) ) = ?) AND t0.Z_ENT = ?)
//2013-05-19 21:13:26.735 P[9609:c07] CoreData: annotation: sql connection fetch time: 0.0008s
//2013-05-19 21:13:26.736 P[9609:c07] CoreData: annotation: total fetch execution time: 0.0012s for 2 rows.
数据构造(- (void) synthesizePhoneGroupsAndIndividuals:(NSManagedObjectContext*)context
):
NSMutableArray* individuals = [NSMutableArray new];//[NSEntityDescription insertNewObjectForEntityForName:@"Individual" inManagedObjectContext:context];
for (NSUInteger i = 0; i < (3 + arc4random() % 100); ++i) {
Individual* indi = [NSEntityDescription insertNewObjectForEntityForName:@"Individual" inManagedObjectContext:context];
indi.contactID = [NSString stringWithFormat:@"cid-%u",i];
[individuals addObject:indi];
}
NSMutableArray* groups = [NSMutableArray new];
for (NSUInteger i = 0; i < 3 + arc4random() % 7; ++i) {
PhoneGroup* group = [NSEntityDescription insertNewObjectForEntityForName:@"PhoneGroup" inManagedObjectContext:context];
group.visible = NO;
NSMutableSet* indis = [group mutableSetValueForKey:@"individuals"];
for (NSUInteger j = 0; j < 3; ++j) {
[indis addObject:[individuals objectAtIndex:(arc4random() % [individuals count])]];
}
[groups addObject:group];
}
[context save:NULL];
测试代码:
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.persistentStoreCoordinator = _persistentStoreCoordinator;
[context performBlockAndWait:^{
[self synthesizePhoneGroupsAndIndividuals:context];
[context reset];
}];
[context performBlockAndWait:^{
NSFetchRequest* r = [[NSFetchRequest alloc] initWithEntityName:@"PhoneGroup"];
NSArray* groups = [context executeFetchRequest:r error:NULL];
if ([groups count]) {
PhoneGroup* group = [groups objectAtIndex:(arc4random() % [groups count])];
[context deleteObject:group];
}
}];