Tôi có một vấn đề rất lạ với quan hệ nghịch đảo trong Dữ liệu lõi và tôi đã giảm thiểu vấn đề của mình xuống một ví dụ tối thiểu, bắt đầu từ một dự án mới trong xcode dựa trên mẫu cửa sổ với sự hỗ trợ cho Core Data (ví dụ, có rất ít ở đó).Quan hệ nghịch đảo không được thiết lập (trong bộ xử lý KVO)
Giả sử chúng tôi có mô hình Dữ liệu chính với ba thực thể: Bộ phận, Nhân viên và Tóm tắt bộ phận (một số loại thực thể đại diện cho một số thống kê về bộ phận). Để đơn giản, chúng tôi chỉ có quan hệ một-một:
DepartmentSummary Department Employee
---------------------------------------------------------
employee <----> department
department <----> summary
Đây là tất cả trong mô hình. Trong application:didFinishLaunchingWithOptions:
chúng ta tạo ra một nhân viên và một bộ phận và thiết lập KVO:
NSManagedObject* employee =
[NSEntityDescription
insertNewObjectForEntityForName:@"Employee"
inManagedObjectContext:[self managedObjectContext]];
[employee addObserver:self forKeyPath:@"department" options:0 context:nil];
NSManagedObject* department =
[NSEntityDescription
insertNewObjectForEntityForName:@"Department"
inManagedObjectContext:[self managedObjectContext]];
[department setValue:employee forKey:@"employee"];
Mục đích của việc xử lý KVO là tạo ra một bản tóm tắt cho bộ phận này càng sớm càng phận của người lao động được thiết lập:
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
[self createSummary:object];
}
createSummary
là đơn giản: nó tạo ra một đối tượng tóm tắt mới và liên kết nó với bộ phận, và sau đó kiểm tra xem mối quan hệ nghịch đảo của bộ phận với đối tượng tóm tắt cũng được đặt là:
- (void) createSummary:(NSManagedObject*)employee
{
NSManagedObject* department = [employee valueForKey:@"department"];
NSManagedObject* summary =
[NSEntityDescription
insertNewObjectForEntityForName:@"DepartmentSummary"
inManagedObjectContext:[self managedObjectContext]];
[summary setValue:department forKey:@"department"];
NSAssert([department valueForKey:@"summary"] == summary,
@"Inverse relation not set");
}
Xác nhận này không thành công. Thật vậy, nếu chúng ta in các đối tượng bách hóa và tóm tắt sau khi bộ phận của bản tóm tắt đã được thiết lập, chúng tôi nhận
entity: DepartmentSummary;
id: ..DepartmentSummary/..AA14> ;
data: {
department = "..Department/..AA13>";
}
cho Nói tóm lại, như mong đợi, nhưng
entity: Department;
id: ..Department/..AA13> ;
data: {
employee = "..Employee/..AA12>";
summary = nil;
}
cho bộ phận (với một nil
tóm lược). Tuy nhiên, nếu chúng ta trì hoãn việc gọi đến createSummary
để nó không chạy cho đến khi phiên bản kế tiếp của runloop:
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
[self performSelector:@selector(createSummary:)
withObject:object
afterDelay:0];
}
sau đó mọi thứ hoạt động như mong đợi.
Trì hoãn việc khẳng định thay vì làm không giúp đỡ: mối quan hệ nghịch đảo thực sự không nhận được thiết trong đồ thị đối tượng, mặc dù nó được đặt trong cơ sở dữ liệu (nếu bạn đã lưu cơ sở dữ liệu, và khởi động lại các ứng dụng, bây giờ tất cả của một đột ngột các mối quan hệ nghịch đảo xuất hiện).
Đây có phải là lỗi trong Dữ liệu chính không? Đây có phải là hành vi được ghi lại mà tôi đã bỏ lỡ không? Tôi có đang sử dụng Dữ liệu cốt lõi theo cách mà nó không được dự định không?
Lưu ý rằng các handler KVO được gọi trong khi Core Data là (tự động) thiết lập (other) nghịch đảo: chúng ta tự đặt lĩnh vực employee
của bộ phận, Core Data tự động cài đặt lĩnh vực department
của nhân viên, và đó lần lượt kích hoạt Trình xử lý KVO. Có lẽ đó chỉ là quá nhiều cho Core Data để xử lý :) Thật vậy, khi chúng tôi đặt
[employee setValue:department forKey:@"department"];
thay vào đó, mọi thứ lại hoạt động như mong đợi.
Mọi con trỏ sẽ được đánh giá cao.
Điều gì sẽ xảy ra nếu bạn đặt tóm tắt ngay lập tức, nhưng trì hoãn xác nhận * của bạn * cho đến lần chạy tiếp theo? – jtbandes
Câu hỏi hay. Tôi sẽ chỉnh sửa câu hỏi để trả lời câu hỏi - về cơ bản, trì hoãn việc xác nhận không giúp được gì. – edsko
hi, tôi nhận thấy tương tự, nó đã hoạt động trước ... – RolandasR