2015-12-27 19 views
6

Tôi gặp sự cố khi tìm nạp đối tượng sau khi được thêm vào trong mối quan hệ. Lần đầu tiên tôi lấy danh mục, luôn tìm thấy, sau đó khi tôi thêm vào mối quan hệ các loại sau không tìm thấy.Không tìm thấy một đối tượng trong coredata sau khi thêm vào mối quan hệ

Mối quan hệ là Many-To-Many.

Ví dụ:

  • Fetch loại với categoryId = 10
  • Tìm thấy loại đối tượng
  • Thêm vào các mối quan hệ đối tượng cha
  • đối tượng Tiếp
  • Nếu một số chuyên mục có cùng id, categoryId = 10 , không được tìm thấy

    NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    
        [private setParentContext:self.model.context]; 
        __block NSError *error = nil; 
    
        [private performBlockAndWait:^{ 
    
         GPDeal *deal = [EKManagedObjectMapper objectFromExternalRepresentation:dic withMapping:[GPDeal objectMapping] inManagedObjectContext:private]; 
         for (NSDictionary *dic in responseObject[@"response"]) { 
    
          GPCategory *category; 
    
          //The first time always found 
          if ((category = [GPCategory MR_findFirstByAttribute:@"catId" withValue:dic[@"mainAttribute"] inContext:private])) { 
           NSLog(@"Found"); 
           [category addDealsObject:deal]; 
    
          } else { 
           NSLog(@"Not Found"); 
    
          } 
    
         } 
        }]; 
    
        NSError *PrivateError = nil; 
        if (![private save:&PrivateError]) { 
         NSLog(@"Unresolved error %@, %@", PrivateError, [PrivateError userInfo]); 
         abort(); 
        } 
    
        if (!error) { 
         //Save on main moc 
         [self.model saveWithErrorBlock:^(BOOL success, NSError *error) { 
          if (!success) { 
           NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
          } 
         }]; 
    
        } else { 
         NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
        } 
    

EDIT:

Giải Quyết, tôi đoán vấn đề của tôi là tôi quên để lưu các bối cảnh chính vào cuối mỗi lần lặp.

 NSManagedObjectContext *backgroundMOC = [self.model backgroundMOC:self.model.context]; 

     [backgroundMOC performBlockAndWait:^{ 

      for (NSDictionary *dic in responseObject[@"response"]) { 

       GPDeal *deal = [EKManagedObjectMapper objectFromExternalRepresentation:dic withMapping:[GPDeal objectMapping] inManagedObjectContext:backgroundMOC]; 

       GPCategory *category; 
       if ((category = [GPCategory MR_findFirstByAttribute:@"catId" withValue:dic[@"mainAttribute"] inContext:backgroundMOC])) { 
        NSLog(@"Found with mainAttribute %@", dic[@"mainAttribute"]); 
        [deal addDealCategoryObject:category]; 
       } 

       if([backgroundMOC hasChanges]) { 
        NSError * error; 
        [backgroundMOC save:&error]; 

        [self.model.context performBlockAndWait:^{ 
         if([self.model.context hasChanges]) { 
          NSError * error; 
          [self.model.context save:&error]; 
         } 
        }]; 
       } 
      } 
     }]; 
+0

Đối tượng 'deal' thuộc về ngữ cảnh nào? Có vẻ như nó phải là một ngữ cảnh khác với 'riêng tư '. Bạn không nên đặt mối quan hệ giữa các đối tượng trong các ngữ cảnh khác nhau. Vượt qua managedObjectID và sau đó lấy nó trong ngữ cảnh 'private' bằng cách sử dụng' objectWithID'. – pbasdf

+0

Tôi đã kiểm tra rồi, nhưng 'thỏa thuận' được tạo bên trong ngữ cảnh riêng – brunobasas

+0

vì vậy vấn đề của bạn chỉ với caregoryId = 10? Lần đầu tiên bạn có 10 trong dic [@ "mainAttribute"] nó tìm thấy thể loại và lần thứ 2 nó không? Thực tế là vấn đề có thể không đến từ MR_findFirstByAttribute cho tôi biết rằng vấn đề có thể là chuỗi chứa số nguyên trong dic [@ "mainAttribute"]. bạn có thể NSLog (@ "ID: -% @ -") để kiểm tra xem ID không có dấu cách trước hay sau? – Mikael

Trả lời

1

Bạn có thể thiếu lưu chuỗi MOC. Để rõ ràng, tôi đã thay thế từ khóa private bằng tên biến backgroundMOC.

Về câu hỏi trên, tôi chỉ có thể giả định rằng dòng NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; cũng tương tự như kỹ thuật để:

- (NSManagedObjectContext *)backgroundMOC:(NSManagedObjectContext *)mainMOC 
{ 
    NSManagedObjectContext * threadManagedObjectContext = [[NSManagedObjectContext alloc] 
          initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [threadManagedObjectContext setParentContext:mainMOC]; 
    [threadManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
    return threadManagedObjectContext; 
} 

qua self.model.context như mainMOC, với một self.model.contextsetMergePolicy.
Tương tự như vậy, tôi phải thừa nhận rằng self.model saveWithErrorBlock là về mặt kỹ thuật giống với:

[mainMOC performBlockAndWait:^{ 
    if([mainMOC hasChanges]) { 
     NSError * error; 
     [mainMOC save:&error]; 
     // handle error 
    } 
}]; 

Nếu vậy, cùng nên nói về backgroundMOC (private tài liệu tham khảo của bạn):

[backgroundMOC performBlockAndWait:^{ 
    if([backgroundMOC hasChanges]) { 
     NSError * error; 
     [backgroundMOC save:&error]; 
     // handle error 
    } 
}]; 

Trong khác các từ, bạn muốn đảm bảo rằng hoạt động lưu backgroundMOCmainMOC được thực hiện từ các chuỗi tương ứng của chúng, với performBlockAndWait.

+0

bạn có thể xem bản cập nhật cuối cùng của mình không? thực sự đánh giá cao – brunobasas

+0

Sự quan tâm là chuỗi mà từ đó bạn thực hiện 'performBlockAndWait' cho' self.model.context save'. Điều đó nên được thực hiện trên luồng chính, nếu không 'UI' của bạn (nói rằng bạn đang sử dụng' NSFetchedResultsController') có thể bị lỗi (xem http://stackoverflow.com/a/6913811/218152). Ngoài ra, nếu bạn cần '[mainMOC save: & error]' mỗi khi bạn '[backgroundMOC save: & error]', bạn có thể không cần 'backgroundMOC' ở vị trí đầu tiên: ý tưởng của' backgroundMOC' là thực hiện các thao tác dài , có thể không phải là trường hợp ở đây. Thông tin thêm: http://stackoverflow.com/search?q=user%3A218152+performBlockAndWait – SwiftArchitect

Các vấn đề liên quan