Tôi có một số tính không hiệu quả trong ứng dụng mà tôi muốn hiểu và khắc phục.Mẫu dữ liệu cốt lõi: cách cập nhật hiệu quả thông tin cục bộ với các thay đổi từ mạng?
thuật toán của tôi là:
fetch object collection from network
for each object:
if (corresponding locally stored object not found): -- A
create object
if (a nested related object locally not found): -- B
create a related object
Tôi đang làm việc kiểm tra trên dây chuyền A và B bằng cách tạo ra một truy vấn ngữ với chính các đối tượng có liên quan của đó là một phần của giản đồ của tôi. Tôi thấy rằng cả hai A (luôn luôn) và B (nếu thực hiện phân nhánh thành phần đó) tạo ra một SQL chọn như:
2010-02-05 01:57:51.092 app[393:207] CoreData: sql: SELECT <a bunch of fields> FROM ZTABLE1 t0 WHERE t0.ZID = ?
2010-02-05 01:57:51.097 app[393:207] CoreData: annotation: sql connection fetch time: 0.0046s
2010-02-05 01:57:51.100 app[393:207] CoreData: annotation: total fetch execution time: 0.0074s for 0 rows.
2010-02-05 01:57:51.125 app[393:207] CoreData: sql: SELECT <a bunch of fields> FROM ZTABLE2 t0 WHERE t0.ZID = ?
2010-02-05 01:57:51.129 app[393:207] CoreData: annotation: sql connection fetch time: 0.0040s
2010-02-05 01:57:51.132 app[393:207] CoreData: annotation: total fetch execution time: 0.0071s for 0 rows.
0.0071s cho một truy vấn là tốt trên một thiết bị 3GS, nhưng nếu bạn thêm 100 trong số này lên, bạn chỉ có một bộ chặn 700ms.
Trong mã của tôi, tôi đang sử dụng một helper để làm những fetches:
- (MyObject *) myObjectById:(NSNumber *)myObjectId {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[self objectEntity]]; // my entity cache
[fetchRequest setPredicate:[self objectPredicateById:objectId]]; // predicate cache
NSError *error = nil;
NSArray *fetchedObjects = [moc executeFetchRequest:fetchRequest error:&error];
if ([fetchedObjects count] == 1) {
[fetchRequest release];
return [fetchedObjects objectAtIndex:0];
}
[fetchRequest release];
return nil;
}
MyObject *obj = [self myObjectById];
if (!obj) {
// [NSEntityDescription insertNewObjectForEntityForName: ... etc
}
tôi cảm thấy điều này là sai và tôi nên làm việc kiểm tra một số cách khác. Nó chỉ nên nhấn cơ sở dữ liệu một lần và nên đến từ bộ nhớ sau đó, phải không? (SQL được thực thi ngay cả đối với các đối tượng mà tôi biết chắc chắn tồn tại cục bộ và nên được nạp vào bộ nhớ với các truy vấn trước đó.) Nhưng, nếu tôi chỉ có myObjectId từ một nguồn bên ngoài, thì đây là điều tốt nhất tôi có thể nghĩ đến. Vì vậy, có lẽ câu hỏi là: nếu tôi có myObjectId (thuộc tính int64 dữ liệu lõi trên MyObject), tôi nên kiểm tra chính xác xem đối tượng địa phương có liên quan có tồn tại trong kho lưu trữ CD hay không? Không. Tải trước toàn bộ tập hợp các kết quả phù hợp và sau đó dự đoán một mảng cục bộ?
(Một giải pháp có thể là di chuyển điều này đến chuỗi nền. Điều này sẽ ổn, ngoại trừ khi tôi nhận được các thay đổi từ chuỗi và làm [moc mergeChangesFromContextDidSaveNotification: aNotification]; (nhận các đối tượng đã thay đổi từ chủ đề nền bằng cách thông báo), thao tác này vẫn bị chặn.)
Liên kết? Tôi đã đọc Hướng dẫn lập trình dữ liệu cốt lõi tại http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html, nhưng tôi không nhớ bất cứ điều gì về Tìm-hoặc-Tạo ở đó . – Jaanus
Đây là liên kết http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174 –
Tôi đã đánh dấu câu trả lời này là câu trả lời vì nó mang ý tưởng tương tự như một số ý tưởng khác (bộ nhớ danh tính có liên quan đến bộ nhớ cache), nhưng có thêm tiền thưởng liên kết đến tài liệu chính thức. Tìm-hoặc-Tạo là chính xác những gì này là về./Đối với bản thân tôi, vì dữ liệu của tôi nhỏ, tôi kết thúc việc tìm nạp toàn bộ đối tượng được đặt vào bộ nhớ, vì dữ liệu đủ nhỏ và tôi cần truy cập vào nó, và cách lưu trữ này cực nhanh. – Jaanus