2010-04-09 24 views
7

Tôi đang làm việc trên một đoạn mã cho ứng dụng iPhone tìm nạp một loạt dữ liệu từ máy chủ và xây dựng các đối tượng từ nó trên máy khách. Nó kết thúc tạo ra khoảng 40.000 đối tượng. Chúng không được hiển thị cho người dùng, tôi chỉ cần tạo các thể hiện của NSManagedObject và lưu chúng vào lưu trữ liên tục.Cách hiệu quả của bộ nhớ để chèn một mảng các đối tượng với Dữ liệu lõi

Tôi có sai khi nghĩ rằng cách duy nhất để làm điều này là tạo một đối tượng đơn lẻ, sau đó lưu ngữ cảnh? là tốt nhất để tạo ra các đối tượng cùng một lúc, sau đó bằng cách nào đó lưu chúng vào bối cảnh sau khi chúng được tạo ra và được lưu trữ trong một số thiết lập hoặc mảng? Nếu vậy, có thể hiển thị một số mã ví dụ về cách thực hiện việc này hay chỉ cho tôi theo hướng mã nơi thực hiện việc này?

Các đối tượng là các mô hình tương đối thẳng về phía trước với các thuộc tính chuỗi hoặc số nguyên và không chứa bất kỳ mối quan hệ phức tạp nào.

Trả lời

5

Trong mọi trường hợp, không lưu sau khi chèn mọi đối tượng hoặc chuẩn bị cho màn trình diễn đáng sợ.

Đây là mã tôi sử dụng để điền một kho dữ liệu lõi khi khởi chạy lần đầu tiên.

#define MAX_UNSAVED_AIRPORTS_BEFORE_SAVE 1000 
int numAirports = 0; 
int numUnsavedAirports = MAX_UNSAVED_AIRPORTS_BEFORE_SAVE; // *** bug. see below 
for (NSDictionary *anAirport in initialAirports) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    Airport *newAirport = [NSEntityDescription insertNewObjectForEntityForName:@"Airport" inManagedObjectContext:managedObjectContext]; 

    newAirport.city   = [anAirport objectForKey:@"city"]; 
    newAirport.code   = [anAirport objectForKey:@"code"]; 
    newAirport.name   = [anAirport objectForKey:@"name"]; 
    newAirport.country_name = [anAirport objectForKey:@"country_name"]; 
    newAirport.latitude  = [NSNumber numberWithDouble:[[anAirport objectForKey:@"latitude"] doubleValue]]; 
    newAirport.longitude = [NSNumber numberWithDouble:[[anAirport objectForKey:@"longitude"] doubleValue]]; 
    newAirport.altitude  = [NSNumber numberWithDouble:[[anAirport objectForKey:@"altitude"] doubleValue]]; 

    numAirports++; 
    numUnsavedAirports++; 
    if (numUnsavedAirports >= MAX_UNSAVED_AIRPORTS_BEFORE_SAVE) { 
     if (![managedObjectContext save:&error]) { 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
     numUnsavedAirports = 0; 
    } 
    [pool release]; 
} 

Cũng đừng quên lưu một lần cuối cùng sau vòng lặp.

Cũng lưu ý rằng một lỗi tồn tại đó sẽ dẫn đến một vụ tai nạn nếu cả ba điều kiện sau đây được đáp ứng:

  1. Kho lưu trữ trống
  2. Bạn có một UITableView với phần
  3. của bạn lần lưu đầu tiên lưu nhiều hơn một đối tượng.

Cách giải quyết trong đoạn code trên là để khởi tạo numUnsavedAirports để MAX_UNSAVED_AIRPORTS_BEFORE_SAVE để đảm bảo tiết kiệm đầu tiên xảy ra sau khi chèn đầu tiên.

Tôi hy vọng điều này sẽ hữu ích.

1

Có thể tốt hơn để tạo một đối tượng và lưu ngữ cảnh.

Bạn có 40k đối tượng. Giả sử rằng việc tạo một NSManagedObject duy nhất mất các đơn vị thời gian x. Đơn vị thời gian 40kx có thể đo lường được. Trong khi tạo đối tượng đang diễn ra, người dùng có thể thoát ứng dụng vì một số lý do; người dùng không thể đoán trước được. Lần sau khi ứng dụng của bạn bắt đầu, bạn sẽ thực hiện lại quá trình này. Nó sẽ không được mong muốn để tạo ra đối tượng 39,999 chỉ để người dùng thoát khỏi ứng dụng và mất tất cả công việc đó.

Nếu ứng dụng của bạn tạo từng đối tượng và lưu, bạn có thể tăng tốc quá trình này một chút. Ứng dụng khởi động và kiểm tra xem liệu ứng dụng có thể hoàn thành tác vụ trong lần chạy cuối cùng hay không. Nếu tác vụ không đầy đủ, nó có thể cố gắng để chọn nơi nó rời đi.

Việc tạo đối tượng đơn lẻ và lưu phương pháp có thể mất nhiều thời gian hơn để hoàn thành nhưng sẽ có khả năng hoàn thành nhiệm vụ nhiều hơn.

Về mức tiêu thụ bộ nhớ, điều này cũng giảm thiểu trạng thái bộ nhớ của ứng dụng của bạn. Ngữ cảnh không theo dõi 40k đối tượng trong bộ nhớ.

+2

Lưu từng đối tượng riêng lẻ sẽ tạo ra hiệu suất khủng khiếp. –

3

Lưu sau mỗi đối tượng sẽ tạo ra hiệu suất rất kém. Bạn nên có một sự cân bằng của tiết kiệm có lẽ mỗi 100 (thử nghiệm sẽ xác định vị trí ngọt) và sau đó theo dõi bạn đang ở đâu trong quá trình xử lý khi người dùng thoát.

Bạn có thời gian để thoát khỏi trạng thái lưu trữ, do đó bạn có thể dễ dàng lưu trữ vị trí của mình trong quá trình xử lý dữ liệu (5 khối 100 đã lưu) và chọn lại nơi bạn đã dừng lại.

Lưu mọi đối tượng riêng lẻ sẽ làm búa đĩa và làm chậm ứng dụng để thu thập thông tin.

+0

Ngoài tư vấn chính xác này, bạn cũng nên cân nhắc đặt lại ManagedObjectContext sau khi lưu để giảm bớt dung lượng bộ nhớ. Nhưng hãy cẩn thận rằng việc đặt lại bối cảnh làm cho bạn mất bất kỳ kết quả trung gian nào trong ngữ cảnh đó. Ví dụ. fetchResults theo đợt cũng đã biến mất. – Bjinse

+0

Tài liệu Apple liên quan có tại đây: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html – Bjinse

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