2012-05-04 21 views
8

Khi sử dụng các loại NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType cho NSManagedObjectContext, có an toàn khi thực hiện các cuộc gọi lồng nhau thực hiện lồng nhau trên cùng một ngữ cảnh không?Nested performBlock: trên NSManagedObjectContext

[backgroundContext performBlock:^{ 
    NSFetchRequest *myRequest = ...; 
    __block NSArray *result= nil; 
    [backgroundContext performBlockAndWait:^{ 
     results = [backgroundContext executeFetchRequest:myRequest error:NULL]; 
    }]; 
}]; 

Dường như có vẻ ngu ngốc nhưng tôi có một cơ sở mã hiện có với nhiều phương pháp trợ giúp đóng gói các cuộc gọi executeFetchRequest. Tôi không muốn đưa ra giả định về việc người gọi đã sử dụng performBlock hay chưa. Ví dụ:

-(void)updateObjects:(BOOL)synchronous 
{ 
    if (YES == synchronous) 
     [self fetchHelper]; 
    else 
    { 
     [backgroundContext performBlock:^{ 
      [self fetchHelper]; 
     }]; 
    } 
} 

-(NSArray*)fetchHelper 
{ 
    [self.backgroundContext performBlockAndWait:^{ 
     //Fetch the objects... 
     [self.backgroundContext executeFetchRequest: (...)]; 
    }]; 
} 

Tôi đã thử nó và nó hoạt động. Nhưng tôi đã học được (một cách khó khăn) phải rất cẩn thận với Core Data và đa luồng.

Trả lời

8

Có, performBlockAndWait là reentrant. Trực tiếp từ ghi chú phát hành của Apple ...

Dữ liệu cốt lõi chính thức hóa mô hình đồng thời cho NSManagedObjectTextextext với các tùy chọn mới. Khi bạn tạo một ngữ cảnh , bạn có thể chỉ định mẫu đồng thời để sử dụng với nó: giới hạn chuỗi, hàng đợi công văn riêng hoặc công văn chính hàng đợi . Tùy chọn NSConfinementConcurrencyType cung cấp cùng một hành vi đã có trên các phiên bản iOS trước 5.0 và là mặc định là . Khi gửi thư đến một ngữ cảnh được tạo với hàng đợi liên kết, bạn phải sử dụng phương thức performBlock: hoặc performBlockAndWait: nếu mã của bạn chưa thực thi trên hàng đợi đó (đối với loại hàng đợi chính ) hoặc trong phạm vi của performBlock. .. gọi (đối với loại hàng đợi riêng tư). Trong các khối được chuyển đến các phương thức , bạn có thể sử dụng các phương thức của NSManagedObjectContext một cách tự do. Phương thức performBlockAndWait: hỗ trợ API reentrancy. Phương thức performBlock: bao gồm một nhóm autorelease và gọi phương thức processPendingChanges khi hoàn thành.

+0

Còn performBlock thì có phải là reentrant không? – malhal

+0

Nó không phải là, điều này được bao gồm trong phiên. Yêu cầu của bạn sẽ xếp hàng nếu bạn gọi performBlock vì nó không đồng bộ. –

+0

chỉ để được rõ ràng, những gì OP đang làm trong bit thứ hai của mã là ok để làm gì ?, Nhưng nó có thể gây ra vấn đề nếu cả hai phương pháp đã "performBlock"? đó là cách chính xác để xem xét điều này? – hokkuk