2014-07-26 32 views
0

我不能让故障在核心数据开火RESTKit:故障不点火

.M

@property (strong, nonatomic) RKObjectManager *objectManager; 
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; 

... 

- (RKObjectManager *)setupObjectManager 
{ 

    NSURL *baseURL = [NSURL URLWithString:kRESTBaseUrl]; 
    AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:baseURL]; 
    RKObjectManager *manager = [[RKObjectManager alloc]initWithHTTPClient:httpClient]; 
    [manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
    [manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON]; 
    [manager.HTTPClient setParameterEncoding:AFJSONParameterEncoding]; 
    [RKMIMETypeSerialization registeredMIMETypes]; 
    [RKObjectManager setSharedManager:manager]; 

    return [RKObjectManager sharedManager]; 

} 

- (RKObjectManager *)getObjectManager 
{ 
    self.objectManager = (!self.objectManager) ? [self setupObjectManager] : self.objectManager; 
    return self.objectManager; 
} 

- (void)getManagedObjectFromAppDelegate 
{ 
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
    self.objectManager = [self getObjectManager]; 

    self.objectManager.managedObjectStore = appDelegate.managedObjectStore; 
    self.managedObjectContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext; 

} 

我取了User地方,如果没有发现,我则取服务器。

找到User后,我在主队列上设置了标签属性,这就是应用程序崩溃的原因,因为故障从不会触发,并且所有内容都是nil

- (void)didFinishFindingUser:(NSString*)user withResults:(NSArray*)results 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (results.count > 0) 
     { 
      self.inviteUser = (User*)[results firstObject]; 
      [self setNameForUser:self.inviteUser]; 
     } 
    }); 
} 

- (void)setNameForUser:(User*)user 
{ 
    [self.activityIndicator stopAnimating]; 
    NSLog(@"User.firstName %@", user.firstName); 
    //Code here to configure the labels 
    //This is where the App crashes as the values are coming as nil 
} 

登录:

2014-07-26 00:46:16.324 App[12455:60b] User.firstName (null) 
(lldb) po user.managedObjectContext 
nil 
(lldb) po user 
<User: 0x1780ac5a0> (entity: User; id: 0xd000000000040008 <x-coredata://99A54059-0A51-402C-9633-B47843B6414B/User/p1> ; data: <fault>) 

(lldb) 

正如你可以看到,我通过NSLog的访问属性火故障,但它不点火。

[User managedObjectContext] == nil 

我能做些什么来解决故障并获得属性?

**更新**

我已经缩小的问题时,我叫main_queue,对象转向到一个故障不利用上下文。

CODE

- (void)didFinishFindingUser:(NSString*)user withResults:(NSArray*)results 
{ 
     if (results.count > 0) 
     { 
      self.inviteUser = (User*)[results firstObject]; 
      NSLog(@"***** Thread BEFORE main_queue: %@", [NSThread currentThread]); 
      NSLog(@"NewUser %@", self.inviteUser); 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       NSLog(@"***** Thread AFTER main_queue: %@", [NSThread currentThread]); 
       NSLog(@"NewUser %@", self.inviteUser); 
      [self setNameForUser:self.inviteUser]; 
      }); 

     } 
} 

- (void)setNameForUser:(User*)user 
{ 

    NSString *firstInitial = user.firstName.length > 0 ? [user.firstName substringToIndex:kInitialIndex] : [kFirstNamePlaceholder substringToIndex:kInitialIndex]; 
    NSString *lastInitial = user.lastName.length > 0 ? [user.lastName substringToIndex:kInitialIndex] : [kLastNmaePlaceholder substringToIndex:kInitialIndex]; 

    self.labelInitials.text = [firstInitial stringByAppendingString:lastInitial]; 
    self.labelName.text = [NSString stringWithFormat:@"%@ %@", user.firstName.length > 0 ? user.firstName : kFirstNamePlaceholder, user.lastName.length > 0 ? user.lastName : kLastNmaePlaceholder]; 
    self.labelUserID.text = [@"@" stringByAppendingString:user.userid]; 
} 

LOG:

2014-07-27 06:01:03.197 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4} 
2014-07-27 06:01:03.198 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380> 
2014-07-27 06:01:03.198 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: { 
    firstName = Lois; 
    lastName = Lane; 
    userid = "lois.lane"; 
}) 
2014-07-27 06:01:03.199 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4} 
2014-07-27 06:01:03.199 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380> 
2014-07-27 06:01:03.200 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: { 
    firstName = Lois; 
    lastName = Lane; 
    userid = "lois.lane"; 
}) 
2014-07-27 06:01:03.201 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4} 
2014-07-27 06:01:03.201 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380> 
2014-07-27 06:01:03.201 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: { 
    firstName = Lois; 
    lastName = Lane; 
    userid = "lois.lane"; 
}) 
2014-07-27 06:01:03.203 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4} 
2014-07-27 06:01:03.203 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380> 
2014-07-27 06:01:03.203 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: { 
    firstName = Lois; 
    lastName = Lane; 
    userid = "lois.lane"; 
}) 
2014-07-27 06:01:03.205 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4} 
2014-07-27 06:01:03.205 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380> 
2014-07-27 06:01:03.206 App[24030:3d07] NewUser <User: 0xd97fc00> (entity: User; id: 0xd97a510 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p2> ; data: { 
    firstName = Lois; 
    lastName = Lane; 
    userid = "lois.lane"; 
}) 

2014-07-27 06:01:03.207 App[24030:60b] ***** Thread AFTER main_queue: <NSThread: 0xdf80f80>{name = (null), num = 1} 
2014-07-27 06:01:03.207 App[24030:60b] User Context (null) 
2014-07-27 06:01:03.207 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4} 
2014-07-27 06:01:03.208 App[24030:60b] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: <fault>) 
2014-07-27 06:01:03.208 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380> 
(lldb) 

应用程序崩溃这里,我尝试在做的没有存在的对象来访问属性。我认为这个问题正在出现?

更新2

- (void)didFinishFindingUser:(NSString*)user withResults:(NSArray*)results 
{ 
    NSManagedObjectID *recordObjectID; 
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 

    if (results.count > 0) 
    { 
     self.inviteUser = (User*)[results firstObject]; 
     recordObjectID = self.inviteUser.objectID; 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSManagedObjectContext *bgndContext = [[NSManagedObjectContext alloc] init]; 
      bgndContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext; 
      bgndContext.persistentStoreCoordinator = appDelegate.managedObjectStore.persistentStoreCoordinator; 
      NSError * error = nil; 
      self.inviteUser = (User *) [bgndContext existingObjectWithID:recordObjectID error:&error]; 
      NSLog(@"***** Thread AFTER main_queue: %@", [NSThread currentThread]); 
      NSLog(@"inviteUser Context %@", [self.inviteUser managedObjectContext]); 
      NSLog(@"inviteUser %@", self.inviteUser); 
      [self setNameForUser:self.inviteUser]; 
     }); 
    } 
} 

LOG:

2014-07-27 06:53:28.390 App[27898:60b] inviteUser Context (null) 
2014-07-27 06:53:28.390 App[27898:60b] inviteUser (null) 
+0

由于无法获取托管对象上下文,因此这不应该是一个故障问题。您应该直接记录用户对象和结果内容。你是如何提出请求和调用完成方法的? – Wain

+0

谢谢。我做了更新。让我知道你是否仍然想看完成方法。 – user1107173

+0

是的。你为什么要自己切换线程?您需要非常小心核心数据上下文和线程。不要在线程之间传递管理对象。 – Wain

回答

1

尝试以下,以获得适当的对象在主线程上下文:

recordObjectID = self.inviteUser.objectID; 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSManagedObjectContext *moc = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;; 
     NSError * error = nil; 

     self.inviteUser = (User *) [moc existingObjectWithID:recordObjectID error:&error]; 

     NSLog(@"***** Thread AFTER main_queue: %@", [NSThread currentThread]); 
     NSLog(@"inviteUser Context %@", [self.inviteUser managedObjectContext]); 
     NSLog(@"inviteUser %@", self.inviteUser); 
     [self setNameForUser:self.inviteUser]; 
    }); 

然而要注意在后台线程和后台管理对象设置self.inviteUser两者是一个坏主意。您应该仅从后台线程返回托管对象ID。另外,如果你有一个对象管理器,那么你应该尝试使用一种方法,在后台获取你的数据,并为你切换到主线程(也就是说,如果你可以帮助它,不直接使用操作) 。

+0

谢谢。这仍然显示为空。我想我正在改变策略。我使用此路由的原因是b/c我得到W'restkit.core_data:RKManagedObjectMappingOperationDataSource.m:243使用无管理对象高速缓存执行管理对象映射: 无法通过标识属性更新现有对象实例。可能会创建重复的对象。错误。“ 我会为此开始一张新票,并将此答案标记为正确。 – user1107173

+0

这里是问题:http://stackoverflow.com/questions/24985937/reskit-duplicate-objects-are-created – user1107173

0

你的对象的管理对象上下文nil,这就是为什么故障不能被解雇。确保在获取用户对象时检查所有属性和上下文。

当涉及到多线程时,RestKit有这样的问题。鉴于你刚刚设置“对象管理器”的丰富代码,你有没有考虑使用普通的Core Data和NSURLSession

+0

谢谢。我做了更新。 – user1107173