2012-07-04 32 views
15

Tôi nhận dữ liệu từ máy chủ web, xử lý dữ liệu trên ngữ cảnh nền riêng tư con được gọi là backgroundMOC. Nó là con của một số mainMOC được liên kết với giao diện người dùng chính, do đó hãy lưu vào các thay đổi giao diện người dùng kích hoạt backgroundMOC. mainMOC là con của một số masterMOC là hàng đợi nền riêng tư được liên kết với cửa hàng liên tục, do đó lưu trên tổng thể lưu vào đĩa.Dữ liệu cốt lõi không thể làm đầy lỗi cho đối tượng sau khi getPermanantIDs

Những gì tôi làm bây giờ là nhận dữ liệu, tạo ra các đối tượng mới trên backgroundMOC, sau đó lưu backgroundMOC (do đó các bản cập nhật giao diện người dùng), tiết kiệm mainMOC, (vì vậy mà tôi có thể gần như tiết kiệm vào đĩa), và lưu masterMOC (vì vậy mà tôi cuối cùng có thể ghi vào đĩa). Vấn đề là khi đối tượng xuất hiện trong giao diện người dùng thông qua bộ điều khiển kết quả đã tìm nạp, thì objectId vẫn là một đối tượng tạm thời.

Điều này gây ra sự cố với vấn đề hàng trùng lặp, nếu tôi nhận được cùng dữ liệu từ máy chủ (01) một đối tượng khác. Khi tôi khởi động lại ứng dụng, đối tượng trùng lặp biến mất, vì vậy tôi biết đó chỉ là vấn đề với ánh xạ id.

Vì vậy, tôi nghĩ rằng tôi có thể thử

[backgroundMOC obtainPermanentIDsForObjects:backgroundMOC.registeredObjects.allObjects error:nil]; 

trước khi lưu ở tất cả (Tôi đã thử sau khi tiết kiệm quá). Tuy nhiên, vì một lý do nào đó, hãy gọi cho dòng này ném một ngoại lệ:

CoreData could not fulfill a fault for... 

Nếu bạn có bất kỳ gợi ý nào có thể dẫn tôi đi đúng hướng, vui lòng chia sẻ. Cảm ơn

Chỉnh sửa: Ok vì vậy ban đầu tôi đã gọi obtainPermanentIDsForObjects trên backgroundMOC, là con của mainMOC, là con của masterMOC. Tôi chuyển nó để tôi có được các id trên mainMOC, và nó giải quyết tất cả các vấn đề của tôi (bây giờ). Tôi có bao giờ phải gọi hàm getPermIds về ngữ cảnh con không?

+0

@Sven tại sao bạn đặt tiền thưởng cho điều này? Bạn có một vấn đề tương tự? – Snowman

+0

Đúng, đó là gần như chính xác cùng một vấn đề tôi đang phải đối mặt. – Sven

+0

"Giải pháp" của tôi là loại bỏ thiết lập chính/chính/con và chỉ sử dụng chính/con, để lưu trữ liên tục được liên kết với hàng đợi chính thay vì hàng đợi nền. – Snowman

Trả lời

19

Đây là một lỗi được biết (bối cảnh lồng nhau không nhận ID vĩnh viễn khi các đối tượng mới được lưu) có thể, và phải được cố định trong một bản phát hành sắp tới ...

Bạn sẽ có thể yêu cầu ID vĩnh viễn mặc dù , nhưng bạn chỉ nên yêu cầu chúng trên các đối tượng đã được chèn vào.

[moc obtainPermanentIDsForObjects:moc.insertedObjects.allObjects error:0]; 

Bạn phải làm điều này trước khi lưu MOC, vì nếu bạn lưu mà không có ID cố định, ID tạm thời sẽ được truyền sang ngữ cảnh gốc. Ví dụ, trong trường hợp của bạn, nơi bạn lưu vào mainMoc, sau đó lấy IDS, backgroundMOC vẫn có các ID tạm thời, do đó lưu trong tương lai từ nó sẽ tạo ra dữ liệu trùng lặp.

Lưu ý rằng việc lấy ID cố định sẽ chuyển sang cơ sở dữ liệu, nhưng nếu bạn đang thực hiện nó trong MOC con của MOC chính, bạn không nên chặn luồng chính trong khi điều này xảy ra.

Vì vậy, trong bạn tiết kiệm từ MOC mức thấp nhất của bạn, bạn có hiệu quả cần phải có một cái gì đó như thế này (với xử lý lỗi thích hợp, tất nhiên) ...

[backgroundMoc performBlock:^{ 
    [backgroundMoc obtainPermanentIDsForObjects:backgroundMoc.insertedObjects.allObjects error:0]; 
    [backgroundMoc save:0]; 
    [mainMoc performBlock:^{ 
     [mainMoc save:0]; 
     [masterMoc performBlock:^{ 
      [masterMoc save:0]; 
     }]; 
    }]; 
}]; 

Có một số trò chơi khác mà bạn có thể chơi, nếu bạn muốn.

Cung cấp một chủng loại trên NSManagedObject tương tự như sau ...

@implementation NSManagedObject (initWithPermanentID) 
- (id)initWithEntity:(NSEntityDescription *)entity insertWithPermanentIDIntoManagedObjectContext:(NSManagedObjectContext *)context { 
    if (self = [self initWithEntity:entity insertIntoManagedObjectContext:context]) { 
     NSError *error = nil; 
     if (![context obtainPermanentIDsForObjects:@[self] error:&error]) { 
      @throw [NSException exceptionWithName:@"CoreData Error" reason:error.localizedDescription userInfo:error.userInfo]; 
     } 
    } 
    return self; 
} 

+ (NSArray*)createMultipleObjects:(NSUInteger)count withEntity:(NSEntityDescription *)entity inManagedObjectContext:(NSManagedObjectContext *)context { 
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; 
    for (NSUInteger i = 0; i < count; ++i) { 
     [array addObject:[[self alloc] initWithEntity:entity insertIntoManagedObjectContext:context]]; 
    } 
    NSError *error = nil; 
    if (![context obtainPermanentIDsForObjects:array error:&error]) { 
     @throw [NSException exceptionWithName:@"CoreData Error" reason:error.localizedDescription userInfo:error.userInfo]; 
    } 
    return array; 
} 
@end 

Bây giờ, trong cái đầu tiên, bạn đang trả tiền để đi vào cơ sở dữ liệu và tạo ra một ID cho từng đối tượng được tạo ra, nhưng nó không phải là nhiều, và nó đang xảy ra trong một chủ đề nền, và mỗi lần nhúng ngắn ...

Ồ, nó không phải là tốt nhất, nhưng nó đã cung cấp hữu ích. Ngoài ra, thứ hai tạo nhiều đối tượng giống nhau và lấy cùng lúc ID của chúng.

Bạn cũng có thể sử dụng MOC được kết nối trực tiếp với PSC và xem các sự kiện DidChange, nhưng cũng giống như cách cũ. Thật không may, bạn không thể có một MOC riêng biệt chỉ cần thực hiện các yêu cầu persistentID và vượt qua ObjectID, mặc dù bạn có thể có một đối tượng nguyên mẫu làm MOC riêng biệt trong DB và cung cấp cho bạn ObjectID của chúng.

Nhà máy sản xuất mẫu thử nghiệm là một mẫu khá phổ biến và nếu bạn sử dụng tuyến đường đó, bạn sẽ dễ dàng thực hiện thay đổi nhỏ khi sửa lỗi cuối cùng tại đây.

EDIT

Để đối phó với Sven ...

Nếu bạn đang tạo mới, đồ thị phức tạp, sau đó bạn cần để có được một ID vĩnh viễn ngay lập tức sau khi tạo. Để giảm số lần truy cập vào cửa hàng, bạn nên tạo tất cả các lần truy cập, sau đó lấy các ID cùng một lúc, sau đó bắt đầu gắn chúng lên.

Thành thật mà nói, tất cả điều này là để giải quyết các lỗi hiện đang tồn tại, rất đáng để làm việc với các bản cập nhật có kích thước vừa và nhỏ. Mã của bạn sẽ giống nhau (không có được) khi các lỗi được sửa. Vì vậy, tôi đề nghị phương pháp này cho nhập khẩu nhỏ hơn.

Nếu bạn đang thực hiện cập nhật quy mô lớn, tôi khuyên bạn nên sử dụng phương pháp "cũ". Tạo một MOC mới được kết nối trực tiếp với PSC. Thực hiện tất cả các thay đổi của bạn ở đó và có ngữ cảnh "sống" của bạn chỉ cần hợp nhất từ ​​các thông báo DidSave đó.

Cuối cùng, về tác động cơ sở dữ liệu của ID cố định. Có thể loại bỏ MOC. Đĩa được nhấn và siêu dữ liệu được thay đổi, nhưng các đối tượng không được lưu giữ.

Thành thật mà nói, tôi đã không làm một thử nghiệm lớn để xem liệu có bất kỳ không gian trống nào, do đó, bạn có thể muốn làm điều đó và quay lại với tôi.

Nhìn vào kích thước tệp cơ sở dữ liệu thực trên đĩa, sau đó tạo 10000 đối tượng, sau đó nhận ID liên tục, giải phóng MOC và xem lại kích thước.

Nếu có tác động, bạn có thể thử xóa các đối tượng hoặc chạy chân không trên cơ sở dữ liệu sau khi cập nhật lớn để xem có hoạt động hay không.

Nếu bạn định tạo nhiều đối tượng mà bạn có thể vứt bỏ, thì không cần phải nhấn vào cơ sở dữ liệu. Bạn có thể chỉ cần đính kèm trực tiếp vào PSC và sử dụng các thông báo trung thành cũ.

+0

Điều này nghe hay. Tôi đã cố gắng sử dụng 'obtainPermanentIDsForObjects: lỗi:' để làm việc xung quanh vấn đề này mà thực sự làm việc, nhưng gây ra một ngoại lệ về các đối tượng không thể truy cập sau này. Tôi cho rằng điều này là do tôi đã thêm đối tượng mới (với ID tạm thời) vào mối quan hệ trước khi lấy ID cố định. Ví dụ của bạn gợi ý để có được ID vĩnh viễn ngay sau khi tạo đối tượng mới. Tôi sẽ cố gắng nếu điều này làm việc cho tôi. Bạn có bất kỳ thông tin nào về những gì sẽ xảy ra nếu bối cảnh với đối tượng mới đó không bao giờ được lưu không? – Sven

+0

Phản hồi được thêm vào để trả lời dưới dạng bản chỉnh sửa. –

0

Tôi đã gặp phải nhiều sự thất vọng với Dữ liệu cốt lõi khi làm việc giữa các luồng nền và nền sau. Trong việc tìm kiếm một giải pháp cho một trong những vấn đề của tôi, tôi chạy ngang qua

Magical Record

tôi đã dành một chút thời gian đi qua các tài liệu và các phương pháp và tôi có thể nói rằng nó đã thực sự làm làm việc với Core Data dễ dàng hơn nhiều. Cụ thể là nó cũng sẽ giúp quản lý nhiều bối cảnh và chủ đề cho bạn.

Bạn có thể muốn kiểm tra.

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