EDIT: Chỉ cần nhìn 2015 WWDC "Có gì mới trong Core Data" (đó là lúc nào cũng là video đầu tiên tôi xem, nhưng tôi đã rất bận rộn trong năm nay) và họ công bố một API mới: NSBatchDeleteRequest
rằng nên hiệu quả hơn bất kỳ giải pháp nào trước đây.
Hiệu quả có nhiều ý nghĩa và thường có nghĩa là một số loại thỏa thuận. Ở đây, tôi giả sử bạn chỉ muốn chứa bộ nhớ trong khi xóa.
Dữ liệu chính có lô tùy chọn hiệu suất, vượt ra ngoài phạm vi của bất kỳ câu hỏi SO nào.
Cách quản lý bộ nhớ phụ thuộc vào cài đặt cho managedObjectContext và fetchRequest của bạn. Xem các tài liệu để xem tất cả các tùy chọn. Đặc biệt, mặc dù, bạn nên giữ những điều này trong tâm trí.
Ngoài ra, hãy nhớ khía cạnh hiệu suất. Loại hoạt động này nên được thực hiện trên một sợi riêng biệt.
Ngoài ra, lưu ý rằng phần còn lại của đồ thị đối tượng của bạn cũng sẽ đi vào chơi (vì cách CoreData xử lý xóa các đối tượng có liên quan.
Về tiêu thụ bộ nhớ, có hai tài sản trên MOC đặc biệt chú ý đến .Trong khi có rất nhiều ở đây, nó không phải là gần như toàn diện. Nếu bạn muốn thực sự thấy những gì đang xảy ra, NSLog MOC của bạn ngay trước và sau mỗi thao tác lưu. Đặc biệt, log registeredObjects và deletedObjects.
MOC có danh sách các đối tượng đã đăng ký. Theo mặc định, nó không giữ lại các đối tượng đã đăng ký. Tuy nhiên, nếu retainsRegisteredObjects là YES, nó sẽ giữ lại tất cả các đối tượng đã đăng ký.
Để xóa cụ thể, setPropagatesDeletesAtEndOfEvent cho MOC biết cách xử lý các đối tượng liên quan. Nếu bạn muốn chúng được xử lý bằng cách lưu, bạn cần đặt giá trị đó thành NO. Nếu không, nó sẽ đợi cho đến khi sự kiện hiện tại được thực hiện
Nếu bạn có bộ đối tượng thực sự lớn, hãy xem xét sử dụng fetchLimit. Trong khi các lỗi không chiếm nhiều bộ nhớ, chúng vẫn mất một số, và hàng ngàn lần tại một thời điểm không đáng kể. Nó có nghĩa là tìm nạp nhiều hơn, nhưng bạn sẽ giới hạn số lượng bộ nhớ
Cũng nên xem xét, bất cứ khi nào bạn có vòng nội bộ lớn, bạn nên sử dụng hồ bơi tự động của riêng mình.
Nếu MOC này có cha/mẹ, việc lưu chỉ di chuyển những thay đổi đó cho phụ huynh. Trong trường hợp này, nếu bạn có một MOC mẹ, bạn chỉ làm cho cái đó phát triển.
Đối với giới hạn bộ nhớ, xem xét việc này (không nhất thiết phải tốt nhất cho trường hợp của bạn - có rất nhiều Core tùy chọn Data - chỉ có bạn mới biết điều gì là tốt nhất cho tình hình của bạn, dựa trên tất cả các tùy chọn bạn
Tôi đã viết một danh mục trên NSManagedObjectContext mà tôi sử dụng để tiết kiệm khi tôi muốn đảm bảo lưu vào cửa hàng sao lưu, rất giống với điều này.Nếu bạn không sử dụng phân cấp MOC, bạn không cần nó, nhưng ... thực sự không có lý do gì để KHÔNG sử dụng một hệ thống phân cấp (trừ khi bạn bị ràng buộc với iOS cũ)
- (BOOL)cascadeSave:(NSError**)error {
__block BOOL saveResult = YES;
if ([self hasChanges]) {
saveResult = [self save:error];
}
if (saveResult && self.parentContext) {
[self.parentContext performBlockAndWait:^{
saveResult = [self.parentContext cascadeSave:error];
}];
}
return saveResult;
}
tôi đổi mã của bạn một chút ...
+ (void)deleteRelatedEntitiesInManagedObjectContext:(NSManagedObjectContext *)context
{
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[context setUndoManager:nil];
[fetch setEntity:[NSEntityDescription entityForName:NSStringFromClass(self) inManagedObjectContext:context]];
[fetch setIncludesPropertyValues:NO];
[fetch setFetchLimit:500];
NSError *error = nil;
NSArray *entities = [context executeFetchRequest:fetch error:&error];
while ([entities count] > 0) {
@autoreleasepool {
for (NSManagedObject *item in entities) {
[context deleteObject:item];
}
if (![context cascadeSave:&error]) {
// Handle error appropriately
}
}
entities = [context executeFetchRequest:fetch error:&error];
}
}
Tối ưu hóa hoạt động: 1. đường xóa -setIncludesPropertyValues; 2. thay đổi giới hạn tìm nạp từ 500 đến 2500 (thực sự!); 3.sử dụng @autoreleasepool –