好的,我想我已经明白了。
我的整体操作流程如下:
-(void)submitRegistration
{
//[[AppDelegate sharedDelegate] drupalLogin];
[self validateFields];
if(fieldsValid)
{
[self createBike];
// save member node will save bike node too if successful
// bike node will not be saved if member node did not save successful
[self saveMemberNode];
// save the updated member node and bike node to Core Data
[self saveLocalRegistration];
// *** ABOVE LINE GETS EXECUTED BEFORE ASYNC REQUEST FINISHES ***
}
}
我的“[self saveLocalRegistration];”代码在异步请求“Block”完成执行之前执行,导致它崩溃。
“saveLocalRegistration”方法调用[managedObjectContext save:& error];
刚刚第一次潜入核心数据。
在我的应用程序中,我要做的一件事就是将一些数据发送到Drupal服务器。
我已将问题缩小到这个范围:
// *** *** ***
// doesn't crash here
// *** *** ***
NSLog(@"bike.brand = %@", bike.brand);
NSLog(@"bike.model = %@", bike.model);
NSLog(@"bike.features = %@", bike.features);
// save new member node to Drupal
[DIOSNode nodeSave:memberData success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSLog(@"Node saved!");
NSDictionary *serverNodeData = (NSDictionary *)responseObject;
NSLog(@"Server node details = %@", serverNodeData);
// set the member's memberId to the newly created Drupal member node's nodeId
member.memberId = [NSNumber numberWithLong:[[serverNodeData valueForKey:@"nid"] longLongValue]];
// *** *** ***
// accessing bike properties here inside this objective c "Block" crashes app
// somehow the above line "member.memberId = .... " doesn't crash despite both being Core Data entities
// *** *** ***
NSLog(@"bike.brand = %@", bike.brand); // <--- CRASH HERE ***
NSLog(@"bike.model = %@", bike.model);
NSLog(@"bike.features = %@", bike.features);
//bike.ownerId = member.memberId;
// save bike node with member id
[self saveBikeNode];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(@"Failed to save node, error: %@", [error localizedDescription]);
}];
从上面的源代码中可以看出,NSLogs的第一个块不会使应用程序崩溃,但是在目标c“Block”内,同一块NSLog会崩溃应用程序。
注意:“[DIOSNode nodeSave:memberData success:....”Objective C块是我认为的异步请求。不知道这是否是一个多线程问题。
bike.brand,bike.model和bike.features是“String”数据类型。
答案 0 :(得分:0)
在块外声明这个并在块内使用它而不是'self'
__block <classname> *blocksafeSelf = self;
答案 1 :(得分:0)
我可以通过在崩溃之前查看调试器的状态来确认,但我的理解是您从不属于它的线程访问托管对象。
您必须在托管对象上下文设计的队列(performBlock和performBlockAndWait)上安排成功块。