2012-11-10 20 views
5

Tôi đang viết một ứng dụng Cookbook và tôi không thể tìm thấy bất kỳ thứ gì về cách lưu dữ liệu của lớp tôi đã tạo (lớp Công thức). Cách duy nhất tôi đã nhìn thấy sẽ là để có thể lưu nội dung của lớp này như một toàn thể mà không lưu riêng rẽ mọi phần tử của lớp cho từng đối tượng bằng cách làm cho phương pháp này cho lớp Recipe tôi:Làm cách nào để lưu đối tượng Objective-C không phải là đối tượng danh sách thuộc tính hoặc có cách nào tốt hơn cho danh sách thuộc tính này?

-(void) writeToFile:(NSString *)file atomically:(BOOL)atomic{ 

} 

Nhưng tôi có hoàn toàn không có ý tưởng làm thế nào tôi muốn đi về việc thực hiện điều này để lưu đối tượng này vào một tập tin bằng cách sử dụng phương pháp này. Một số thuộc tính là:

NSString* name; 
UIImage* recipePicture; 
NSDate* dateAdded; 
NSMutableArray* ingredients; //The contents are all NSStrings. 

Có ai biết cách tiết kiệm một đối tượng của lớp Công thức không? Điều đó khiến tôi phát điên vì không thể hình dung ra được. Mọi sự trợ giúp sẽ rất được trân trọng. Tôi đã có một .plist mang tên "RecipeData.plist". Tôi chỉ cần viết mọi thuộc tính cho plist và khởi tạo một đối tượng mới của công thức với các thuộc tính đó trong thời gian chạy?

Trả lời

5

Áp dụng:

@interface Recipe : NSObject<NSCoding> 

Thực hiện:

- (void)encodeWithCoder:(NSCoder *)coder 
{ 
    [coder encodeObject:name_ forKey:@"name"]; 
    [coder encodeObject:recipePicture_ forKey:@"recipePicture"]; 
    [coder encodeObject:dateAdded_ forKey:@"dateAdded"]; 
    [coder encodeObject:ingredients_ forKey:@"ingredients"]; 

}

// Decode an object from an archive 
- (id)initWithCoder:(NSCoder *)coder 
{ 
    self = [super init]; 
    if (self!=NULL) 
    { 
     name_ = [coder decodeObjectForKey:@"name"]; 
     recipePicture_ = [coder decodeObjectForKey:@"recipePicture"]; 
     dateAdded_ = [coder decodeObjectForKey:@"dateAdded"]; 
     ingredients_ = [coder decodeObjectForKey:@"ingredients"]; 
    } 
    return self; 
} 

Bây giờ trong bạn tiết kiệm:

- (void) save:(NSString*)path recipe:(Recipe*)recipe 
{ 
    NSMutableData* data=[[NSMutableData alloc] init]; 
    if (data) 
    { 
     NSKeyedArchiver* archiver=[[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
     if (archiver) 
     { 
      [archiver encodeInt:1 forKey:@"Version"]; 
      [archiver encodeObject:recipe forKey:@"Recipe"]; 
      [archiver finishEncoding]; 

      [data writeToFile:path atomically:YES]; 

     } 
    } 
} 

Và trong tải:

- (Recipe*) load:(NSString*)path 
{ 
    Recipe* ret=NULL; 
    NSData* data=[NSData dataWithContentsOfFile:path]; 
    if (data) 
    { 
     NSKeyedUnarchiver* unarchiver=[[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
     if (unarchiver) 
     { 
      int version=[unarchiver decodeIntForKey:@"Version"]; 
      if (version==1) 
      { 
       ret=(Recipe*)[unarchiver decodeObjectForKey:@"Recipe"]; 
      } 
      [unarchiver finishDecoding]; 
     } 
    } 
    return ret; 
} 
+0

Bạn nên cập nhật điều này với hai phần ba câu trả lời khác - cách mã hóa nó thành đối tượng NSData để lưu trữ trong danh sách thuộc tính và cách giải mã dữ liệu từ danh sách thuộc tính. – rmaddy

+0

Như tôi đã nói trong phần bình luận dưới đây, cảm ơn các bạn đã dành thời gian để chỉ cho tôi cách làm điều này. Nó thực sự là một trợ giúp lớn. – crarho

+0

Bạn nên gọi 'self = [super initWithCoder: coder];' thay vì 'self = [super init];'. Nếu không, lớp cha của bạn sẽ không có dữ liệu được mã hóa của nó. –

2

Một lựa chọn (ngoài mã hóa/giải mã) là để lưu trữ từng thuộc tính của lớp học của bạn trong từ điển. Sau đó, bạn viết từ điển vào tập tin. Bí quyết là để đảm bảo rằng mọi đối tượng bạn đưa vào từ điển đều được phép trong một plist. Trong số bốn thuộc tính bạn hiển thị, tất cả trừ UIImage có thể được lưu trữ dưới dạng.

-(BOOL)writeToFile:(NSString *)file atomically:(BOOL)atomic{ 
    NSMutableDictionary *data = [NSMutableDictionary dictionary]; 

    [data setObject:name forKey:@"name"]; 
    [data setObject:dateAdded [email protected]"dataAdded"]; 

    NSDate *imageData = UIImagePNGRepresentation(recipePicture); 
    [data setObject:imageData forKey:@"recipePicture"]; 

    // add the rest 

    return [data writeToFile:file atomically:YES]; 
} 

Tôi đã cập nhật điều này để trả lại BOOL. Nếu nó không thành công, nó có nghĩa là một trong hai điều:

  1. Các tập tin không phù hợp
  2. Bạn đã cố gắng để lưu một đối tượng thân thiện phi plist trong dictonary

Bạn cần phải thêm mã để tránh cố gắng thêm nil đối tượng nếu bạn có. Điều quan trọng là đảm bảo rằng tất cả các phím là chuỗi và chỉ các đối tượng thân thiện với plist được lưu trữ (NSString, NSNumber, NSDate, NSValue, NSData, NSArray và NSDictionary).

+0

Cảm ơn bạn rất nhiều vì đã giúp đỡ. Nó rất được đánh giá cao - vấn đề này đã làm tôi thất vọng một thời gian. – crarho