核心数据NSManagedObject isFault在prepareForDeletion [英] Core Data NSManagedObject isFault inside prepareForDeletion

查看:172
本文介绍了核心数据NSManagedObject isFault在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> s和 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 Individuals and PhoneGroups

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 Individuals 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 live managedObjectContext 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆