2014-07-26 35 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