核心数据NSManagedObject isFault在prepareForDeletion [英] Core Data NSManagedObject isFault inside prepareForDeletion
问题描述
我在 NSManagedObject
中的 - prepareForDeletion
中做一些处理。然而,当我尝试访问这个类的一些属性,他们返回给我作为 nil
(即使我知道他们不是 nil
)。所以我检查我的对象是否是 [self isFault]
,并返回 YES
。
那么当我在 - prepareForDeletion
中时,如何使对象访问资源?
PhoneGroup.m(NSManagedObject)
- (void)prepareForDeletion {
[super prepareForDeletion];
NSArray * individuals = [self.individuals allObjects]; //个人是nil
for(int i = 0; i <[个人计数]; i ++){
个人*个人= [个人objectAtIndex:i];
BOOL individualExistsInOtherGroups = [individual.phoneGroups count]> 1;
BOOL individualAddedAsAdditionalContactToReminder = [individual.reminders count]> 0;
//如果个人在其他组中不存在并且没有添加到任何提醒中,我们可以删除个人
if(!individualExistsInOtherGroups&&!individualAddedAsAdditionalContactToReminder& &![individual isDeleted]){
[[CoreDataHelper sharedInstance] deleteEntity:individual inManagedObjectContext:self.managedObjectContext];
}
}
//发布通知以通知所有感兴趣的VC,以便他们可以刷新GUI
[[NSNotificationCenter defaultCenter] postNotificationName:RMContactDeletedNotification object:self] ;
DLog(@联系已删除的通知已发送);
}
型号资讯:
$ b
PhoneGroup
与删除规则无效的个人
具有反对多关系。
个人
与 PhoneGroup
是个人$ c>的超类。
PhoneGroup
s 这里是一个可视化效果更好的图片。
>
< h2> EDIT:我在这个问题上有更多的发现
PhoneGroup
与提醒
的关系。如果 PhoneGroup
在删除时与提醒
没有关系,则 strong> fault。
提醒
具有可选的与< code& / code>与删除规则无效。
联系人
code>提醒
这是什么意思?
EDIT 2:有关此问题的更多资讯
我尝试Dan Shelly的替代解决方案来取得 Individual
()的
)是 self.managedObjectContext
> PhoneGroup nil
里面 - prepareForDeletion
这是什么意思?
为什么
[self.individuals allObjects] / code> return nil?
br />
发现你的 managedObjectContext
是 nil
后,你可以说你的对象已经。
这可能是由上下文 reset
或释放引起的,而你保持对你的对象的强引用。 >
然而,这不会解释如何在 prepareForDeletion
方法内发生这种情况。
此方法在删除实时上下文时调用一个对象( [context deleteObject:...]
)。
这意味着你调用 prepareForDeletion
手动(
[object prepareForDeletion]
),或者另一个线程在中间删除期间重置/取消分配您的上下文。
注意:下面的代码将工作,因为你有一个有效的
objectID
managedObjectContext
在您的对象上设置。
< 但,我可能会遇到一个问题,因为您访问数据的方式效率不高(将在稍后解释):
如果您删除的对象( PhoneGroup
)个人
关系没有故障,CoreData将forst访问存储,第一次旅行)。你会有故障作为该关系中包含的对象(N个对象),你的循环将逐个访问它们(N次到存储)。仍然在循环中,你访问每个对象的关系(2关系船舶 phoneGroups
和提醒
==> 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];
[rsetReturnsObjectsAsFaults:NO];
[r setIncludesPendingChanges:YES];
*现在剩下的就是:
NSManagedObjectContext * context = [self managedObjectContext];
NSArray * individuals = [context executeFetchRequest:r error:NULL];
for(Individual * individual in individual){
[context deleteObject:individual];
}
这是通过单次(1) case,因为你不直接依赖你的关系,只要你的对象有它的 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:注释:总读取执行时间:0.0008s,3行。
// 2013-05-19 21:34:42.715 P [9666:c07] CoreData:注释:objectID为0x8572b70< x-coredata:// CBE585F2-552D-4FDE -AAEA-2C9C7984FAC9 / PhoneGroup / p21>从数据库履行。有3行
// 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:注释:sql连接获取时间:0.0005s
// 2013-05-19 21:34:42.717 [9666:c07] CoreData:注释:总提取执行时间:0.0008s,用于1行。
// 2013-05-19 21:34:42.718 P [9666:c07] CoreData:注释:从数据库满足以下错误:0x818cad0 // 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:注释:sql连接提取时间:0.0004s
// 2013-05-19 21:34:42.719 P [9666:c07] CoreData:注释:总提取执行时间:0.0008s,用于1行。
// 2013-05-19 21:34:42.719 P [9666:c07] CoreData:注释:objectID为0x818cad0的一对多关系错误phoneGroupsx-coredata:// CBE585F2-552D-4FDE -AAEA-2C9C7984FAC9 / Individual / p4>从数据库履行。有1行
// 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:注释:sql连接获取时间:0.0005s
// 2013-05-19 21:34:42.721 P [9666:c07] CoreData:注释:总提取执行时间:0.000行,0行。
// 2013-05-19 21:34:42.721 P [9666:c07] CoreData:注释:对象ID为0x818cad0< x-coredata:// CBE585F2-552D-4FDE -AAEA-2C9C7984FAC9 / Individual / p4>从数据库履行。有0行
// 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:注释:sql连接获取时间:0.0004s
// 2013-05-19 21:34:42.722 P [9666:c07] CoreData:注释:总提取执行时间:0.0008s,用于1行。
// 2013-05-19 21:34:42.723 P [9666:c07] CoreData:注释:从数据库满足以下错误:0x818cb90 // 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:注释:sql连接获取时间:0.0004s
// 2013-05-19 21:34:42.724 P [9666:c07] CoreData:注释:总提取执行时间:0.0008s,用于1行。
// 2013-05-19 21:34:42.724 P [9666:c07] CoreData:注释:objectID 0x818cb90的一对多关系错误phoneGroups // 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:注释:sql连接获取时间:0.0004s
// 2013-05-19 21:34:42.726 P [9666:c07] CoreData:注释:总提取执行时间:0.000行,0行。
// 2013-05-19 21:34:42.726 P [9666:c07] CoreData:注释:一对多关系错误提醒对象ID 0x818cb90< x-coredata:// CBE585F2-552D-4FDE -AAEA-2C9C7984FAC9 / Individual / p16>从数据库履行。有0行
// 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:注释:sql连接获取时间:0.0004s
// 2013-05-19 21:34:42.727 P [9666:c07] CoreData:注释:总提取执行时间:0.0008s,用于1行。
// 2013-05-19 21:34:42.728 P [9666:c07] CoreData:注释:从数据库满足以下错误:0x818cba0 // 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:注释:sql连接获取时间:0.0004s
// 2013-05-19 21:34:42.729 P [9666:c07] CoreData:注释:总提取执行时间:0.0008s,用于4行。
// 2013-05-19 21:34:42.729 P [9666:c07] CoreData:注释:objectID为0x818cba0< x-coredata:// CBE585F2-552D-4FDE的to-many关系错误phoneGroups -AAEA-2C9C7984FAC9 / Individual / p17>从数据库履行。有4行
// 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:注释:sql连接获取时间:0.0004s
// 2013-05-19 21:34:42.731 P [9666:c07] CoreData:注释:总提取执行时间:0.000行,为0行。
// 2013-05-19 21:34:42.731 P [9666:c07] CoreData:注释:对象ID为0x818cba0< x-coredata:// CBE585F2-552D-4FDE -AAEA-2C9C7984FAC9 / Individual / p17>从数据库履行。已获得0行
建议的实施效果:
// 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.ZVSIBLE 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:注释:sql连接提取时间:0.0008s
// 2013-05-19 21:13:26.736 P [9609:c07] CoreData:annotation:total读取执行时间:0.0012s为2行。
数据构造( - (void)synthesizePhoneGroupsAndIndividuals:(NSManagedObjectContext *)context
):
NSMutableArray * individuals = [NSMutableArray new]; // [NSEntityDescription insertNewObjectForEntityForName :@IndividualinManagedObjectContext:context];
for(NSUInteger i = 0; i <(3 + arc4random()%100); ++ i){
Individual * indi = [NSEntityDescription insertNewObjectForEntityForName:@IndividualinManagedObjectContext:context];
indi.contactID = [NSString stringWithFormat:@cid-%u,i];
[individual addObject:indi];
}
NSMutableArray * groups = [NSMutableArray new];
for(NSUInteger i = 0; i <3 + arc4random()%7; ++ i){
PhoneGroup * group = [NSEntityDescription insertNewObjectForEntityForName:@PhoneGroupinManagedObjectContext:context];
group.visible = NO;
NSMutableSet * indis = [group mutableSetValueForKey:@individuals];
for(NSUInteger j = 0; j <3; ++ j){
[indis addObject:[individual objectAtIndex:(arc4random()%[individual 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];
}
}];
I'm doing some processing inside - prepareForDeletion
in a NSManagedObject
. However when I try to access some properties of this class they are returned to me as nil
(even though I know they are not nil
). So I check if my object is fault [self isFault]
and it returns YES
.
So how can I make the object "not fault" when I'm inside - prepareForDeletion
because I need to access a property?
PhoneGroup.m (NSManagedObject)
- (void)prepareForDeletion {
[super prepareForDeletion];
NSArray *individuals = [self.individuals allObjects]; // individuals is nil
for (int i = 0; i < [individuals count]; i++) {
Individual *individual = [individuals objectAtIndex:i];
BOOL individualExistsInOtherGroups = [individual.phoneGroups count] > 1;
BOOL individualAddedAsAdditionalContactToReminder = [individual.reminders count] > 0;
// We can delete the individual if individual does not exist in other groups and is not added to any reminders
if (!individualExistsInOtherGroups && !individualAddedAsAdditionalContactToReminder && ![individual isDeleted]) {
[[CoreDataHelper sharedInstance] deleteEntity:individual inManagedObjectContext:self.managedObjectContext];
}
}
// Post a notification to notify all interested VC so they can refresh the GUI
[[NSNotificationCenter defaultCenter] postNotificationName:RMContactDeletedNotification object:self];
DLog(@"Contact deleted notification sent");
}
Model information:
PhoneGroup
has an inverse to-many relationship to Individual
with delete rule nullify.
Individual
has an inverse to-many relationship to PhoneGroup
with delete rule nullify.
Contact
is a superclass for Individual
s and PhoneGroup
s
Here's an image to visualize better.
EDIT: I have made some more findings on this issue
PhoneGroup
only seems to fault when there is a relationship to a Reminder
. If a PhoneGroup
does not have a relationship to a Reminder
when it is being deleted it is not fault.
Reminder
has an optional inverse to-many relationship to Contact
with delete rule nullify.
Contact
has an optional inverse to-many relationship to Reminder
with delete rule nullify.
What gives of this?
EDIT 2: More findins on the issue
I tried Dan Shelly's alternative solution to do a fetch of Individual
s however even the self.managedObjectContext
of the NSManagedObject
(PhoneGroup
) is nil
inside - prepareForDeletion
what does this imply?
Why does
[self.individuals allObjects]
return nil?
Edit:
After discovering that your managedObjectContext
is nil
it is safe to say that your object has been disowned by its context.
This might be caused by a context reset
or deallocation, while you maintain a strong reference to your object.
However this won't explain how this happen inside the prepareForDeletion
method.
This method is invoked when a live context is deleting an object ([context deleteObject:...]
).
This would mean that either you invoke prepareForDeletion
manually ([object prepareForDeletion]
), or that another thread is reseting/deallocating your context in mid-delete.
Note: The below code will work given that you have a valid
objectID
and a livemanagedObjectContext
set on your object.
However, I might have a work around as the way you access your data is somewhat inefficient (will explain shortly):
If your deleted object (PhoneGroup
) individuals
relationship is not faulted, CoreData will forst access the store to fault the relationship (1st trip). you will then have faults as objects contained in that relationship (N objects), your loop will access them one by one (N trips to the store). still in the loop, you access each object for its relationships (2 relations ships, phoneGroups
and reminders
==> 2 trips to the store PER ITEM).
In conclusion: 1 + N + 2*N = 3*N +1 trips to the store (worst case).
This could be accomplished in a much simpler way:
* create this fetch request:
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];
* now all that is left is:
NSManagedObjectContext* context = [self managedObjectContext];
NSArray* individuals = [context executeFetchRequest:r error:NULL];
for (Individual* individual in individuals) {
[context deleteObject:individual];
}
this is accomplished with a single (1) trip to the store in the worst case, and since you don't rely on you relationship directly, this should work as long as your object has its objectID
.
Apendix:
Current implementation performance (SQLite debug):
//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
Proposed implementation performance:
//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.
Data construction (- (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];
Testing code:
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];
}
}];
这篇关于核心数据NSManagedObject isFault在prepareForDeletion的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!