Cocoa touch 在MOCs performBlock中使用对象的获取永久性会导致奇怪的错误

Cocoa touch 在MOCs performBlock中使用对象的获取永久性会导致奇怪的错误,cocoa-touch,core-data,Cocoa Touch,Core Data,iam使用线程中MOC的新工作方式 - (void) parse:(NSDictionary *)serviceResponseDictionary onParseFinished:(ParseFinished)onParseFinished onParseFailed:(ParseFailed)onParseFailed { NSManagedObjectContext * parent = [NSManagedObjectContext MR_defaultContext]; //

iam使用线程中MOC的新工作方式

- (void) parse:(NSDictionary *)serviceResponseDictionary onParseFinished:(ParseFinished)onParseFinished onParseFailed:(ParseFailed)onParseFailed
{
    NSManagedObjectContext * parent = [NSManagedObjectContext MR_defaultContext]; // NSMainQueueConcurrencyType
    NSManagedObjectContext * child = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [child setParentContext:parent];

    [child performBlock:^(){

        Class parsedItemsClass = [NSNull class]; 
        NSMutableArray * parsedItemsObjectIDs;
        NSMutableArray * parsedItemsObjects;

        // processing the serviceResponseDictionary here 
        // creating / deleting / modifying Managed objects in child here

        NSError * error;
        [child save:&error];
        // handle and check error here 

        [child obtainPermanentIDsForObjects:parsedItemsObjects error:&error];
        // handle and check error here 

        // obtain pernament IDs here, if remove, it doesnt crash
        parsedItemsObjectIDs = [[NSMutableArray alloc] initWithCapacity:[parsedItemsObjects count]];

        for (NSManagedObject * mo in parsedItemsObjects) {
            [parsedItemsObjectIDs addObject:mo.objectID];
        }

        [parent performBlock:^(){

            NSError * error;
            [parent save:&error];
            // handle and check error here 

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                onParseFinished(parsedItemsClass, parsedItemsObjectIDs);
            }];
        }];
    }];
}
问题是,当我打电话的时候

[child obtainPermanentIDsForObjects:parsedItemsObjects error:&error];
- (void) parse:(NSDictionary *)serviceResponseDictionary onParseFinished:(ParseFinished)onParseFinished onParseFailed:(ParseFailed)onParseFailed
{
    NSManagedObjectContext * parent = [NSManagedObjectContext MR_defaultContext]; // NSMainQueueConcurrencyType
    NSManagedObjectContext * child = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [child setParentContext:parent];

    [child performBlock:^(){

        Class parsedItemsClass = [NSNull class]; 
        NSMutableArray * parsedItemsObjectIDs;
        NSMutableArray * parsedItemsObjects;

        // processing the serviceResponseDictionary here 
        // creating / deleting / modifying Managed objects in child here

        NSError * error;
        [child save:&error];
        // handle and check error here 

        [child obtainPermanentIDsForObjects:parsedItemsObjects error:&error];
        // handle and check error here 

        // obtain pernament IDs here, if remove, it doesnt crash
        parsedItemsObjectIDs = [[NSMutableArray alloc] initWithCapacity:[parsedItemsObjects count]];

        for (NSManagedObject * mo in parsedItemsObjects) {
            [parsedItemsObjectIDs addObject:mo.objectID];
        }

        [parent performBlock:^(){

            NSError * error;
            [parent save:&error];
            // handle and check error here 

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                onParseFinished(parsedItemsClass, parsedItemsObjectIDs);
            }];
        }];
    }];
}
要获取域名ID

- (void) parse:(NSDictionary *)serviceResponseDictionary onParseFinished:(ParseFinished)onParseFinished onParseFailed:(ParseFailed)onParseFailed
{
    NSManagedObjectContext * parent = [NSManagedObjectContext MR_defaultContext]; // NSMainQueueConcurrencyType
    NSManagedObjectContext * child = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [child setParentContext:parent];

    [child performBlock:^(){

        Class parsedItemsClass = [NSNull class]; 
        NSMutableArray * parsedItemsObjectIDs;
        NSMutableArray * parsedItemsObjects;

        // processing the serviceResponseDictionary here 
        // creating / deleting / modifying Managed objects in child here

        NSError * error;
        [child save:&error];
        // handle and check error here 

        [child obtainPermanentIDsForObjects:parsedItemsObjects error:&error];
        // handle and check error here 

        // obtain pernament IDs here, if remove, it doesnt crash
        parsedItemsObjectIDs = [[NSMutableArray alloc] initWithCapacity:[parsedItemsObjects count]];

        for (NSManagedObject * mo in parsedItemsObjects) {
            [parsedItemsObjectIDs addObject:mo.objectID];
        }

        [parent performBlock:^(){

            NSError * error;
            [parent save:&error];
            // handle and check error here 

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                onParseFinished(parsedItemsClass, parsedItemsObjectIDs);
            }];
        }];
    }];
}
当我离开街区时,我得到了

NSManagedObject Context Queue Serial
i get an EXC_BAD_ACCESS on objc_msgSend

libobjc.A.dylib`objc_msgSend:
0x34eb9f68:  teq.w  r0, #0
0x34eb9f6c:  beq    0x34eb9faa               ; objc_msgSend + 66
0x34eb9f6e:  push.w {r3, r4}
HERE 0x34eb9f72:  ldr    r4, [r0]
0x34eb9f74:  lsr.w  r9, r1, #2
0x34eb9f78:  ldr    r3, [r4, #8]
...
- (void) parse:(NSDictionary *)serviceResponseDictionary onParseFinished:(ParseFinished)onParseFinished onParseFailed:(ParseFailed)onParseFailed
{
    NSManagedObjectContext * parent = [NSManagedObjectContext MR_defaultContext]; // NSMainQueueConcurrencyType
    NSManagedObjectContext * child = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [child setParentContext:parent];

    [child performBlock:^(){

        Class parsedItemsClass = [NSNull class]; 
        NSMutableArray * parsedItemsObjectIDs;
        NSMutableArray * parsedItemsObjects;

        // processing the serviceResponseDictionary here 
        // creating / deleting / modifying Managed objects in child here

        NSError * error;
        [child save:&error];
        // handle and check error here 

        [child obtainPermanentIDsForObjects:parsedItemsObjects error:&error];
        // handle and check error here 

        // obtain pernament IDs here, if remove, it doesnt crash
        parsedItemsObjectIDs = [[NSMutableArray alloc] initWithCapacity:[parsedItemsObjects count]];

        for (NSManagedObject * mo in parsedItemsObjects) {
            [parsedItemsObjectIDs addObject:mo.objectID];
        }

        [parent performBlock:^(){

            NSError * error;
            [parent save:&error];
            // handle and check error here 

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                onParseFinished(parsedItemsClass, parsedItemsObjectIDs);
            }];
        }];
    }];
}
代码

- (void) parse:(NSDictionary *)serviceResponseDictionary onParseFinished:(ParseFinished)onParseFinished onParseFailed:(ParseFailed)onParseFailed
{
    NSManagedObjectContext * parent = [NSManagedObjectContext MR_defaultContext]; // NSMainQueueConcurrencyType
    NSManagedObjectContext * child = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [child setParentContext:parent];

    [child performBlock:^(){

        Class parsedItemsClass = [NSNull class]; 
        NSMutableArray * parsedItemsObjectIDs;
        NSMutableArray * parsedItemsObjects;

        // processing the serviceResponseDictionary here 
        // creating / deleting / modifying Managed objects in child here

        NSError * error;
        [child save:&error];
        // handle and check error here 

        [child obtainPermanentIDsForObjects:parsedItemsObjects error:&error];
        // handle and check error here 

        // obtain pernament IDs here, if remove, it doesnt crash
        parsedItemsObjectIDs = [[NSMutableArray alloc] initWithCapacity:[parsedItemsObjects count]];

        for (NSManagedObject * mo in parsedItemsObjects) {
            [parsedItemsObjectIDs addObject:mo.objectID];
        }

        [parent performBlock:^(){

            NSError * error;
            [parent save:&error];
            // handle and check error here 

            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                onParseFinished(parsedItemsClass, parsedItemsObjectIDs);
            }];
        }];
    }];
}

如果在保存子上下文之前调用
获取对象的永久性属性
,会发生什么情况?如果在保存之前放置,它会工作!!!但是为什么呢?我记得在什么地方读过,但是我现在没有参考资料。看。