2012-05-04 43 views
7

Tôi có mảng này có thể thay đổi tên myWallet với kê khai tài sản của mình:tiết kiệm một NSMutableArray sử dụng NSUserDefaults không làm việc

@property (nonatomic, strong) NSMutableArray *myWallet; 

mảng này đã được lấp đầy bởi Thủy, đó là một đối tượng. Tôi tạo một thể hiện mới của một Card từ một View Controller khác, vì vậy tôi sử dụng một phương thức delegate để có thể truyền thẻ được tạo trên View Controller ban đầu của tôi, đó là một Table View Controller. Bên dưới là phương thức ủy nhiệm

- (void)addCardViewController:(AddCardViewController *)sender didCreateCard:(Card *)newCard 
{ 
    // insert a new card 

    self.myCard = newCard; 
    [self.myWallet addObject:self.myCard]; 

    [self.tableView reloadData]; 
} 

Cho đến nay, tôi có thể tạo phiên bản mới của Thẻ và khi tôi thực hiện, một ô bảng mới xuất hiện trong bộ điều khiển xem ban đầu của tôi (Thẻ Wallet VC).

Điều tôi muốn là khi người dùng hoàn tất việc sử dụng ứng dụng, (các) cá thể đã tạo của Thẻ mà người đó tạo trước đó vẫn xuất hiện vào lần chạy ứng dụng tiếp theo. Vì vậy, tôi đã sử dụng NSUserDefaults để làm điều này. Phương pháp bên dưới là cách tôi đang sử dụng NSUserDefaults để lưu.

- (void)saveMyWallet 
{ 

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

    [defaults setObject:self.myWallet forKey:@"myWalletArray"]; 

    [defaults synchronize]; 
    NSLog(@"I am saved"); 
} 

Tôi gọi phương thức này bên trong didSelectRowAtIndexPath. Khi tôi chạy ứng dụng, sau đó tạo một phiên bản mới của Thẻ, hãy nhấp vào ô bảng, điều này xuất hiện trên nhật ký của tôi.

2012-05-04 14:51:00.900 CardWallet[24998:f803] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '("<Card: 0x6aa02f0>")' of class '__NSArrayM'. 
Note that dictionaries and arrays in property lists must also contain only property values. 

Lý do có thể là gì? Và bạn có thể gợi ý cho tôi những cách tôi có thể làm được không.

Xin cảm ơn trước.

+0

Đầu tiên loại bỏ thuộc tính mảng của bạn và sau đó kiểm tra những giá trị có trong mảng của bạn bằng cách sử dụng nslog đi cho khóa – vishiphone

Trả lời

4

lớp Thẻ của bạn cũng phải phù hợp với NSCoding Protocol bởi vì bạn chỉ có thể lưu trữ NSData, NSString, NSArray, NSDictionaryNSNumber với NSUserDefaults. Điều đó có nghĩa, bạn cần phải thêm hai phương pháp để lớp học của bạn:

- (void)encodeWithCoder:(NSCoder *)enCoder { 
    [super encodeWithCoder:enCoder]; 

    [enCoder encodeObject:instanceVariable forKey:INSTANCEVARIABLE_KEY]; 

    // Similarly for the other instance variables. 
    .... 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 

    if(self = [super initWithCoder:aDecoder]) { 
     self.instanceVariable = [aDecoder decodeObjectForKey:INSTANCEVARIABLE_KEY]; 

     // similarly for other instance variables 
     .... 
    } 

    return self; 
} 

Sau đó tạo một NSData NSKeyedArchiver trước khi lưu trữ nó để NSUserDefaults. Như thế này:

NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; 
NSData *yourArrayAsData = [NSKeyedArchiver archivedDataWithRootObject:yourArray]; 
[ud setObject:sharesAsData forKey:kA_KEY_FOR_USERDEFAULTS]; 
+1

Điều đó là không đủ, NSUserDefaults sẽ không tự động mã hóa chúng cho bạn. Bạn cần phải làm như vậy cho mình! – ssteinberg

+1

Quyền của bạn, ... đã cập nhật câu trả lời của tôi –

+0

Được rồi, tôi sẽ thử câu hỏi này – Grauzten

0

Nếu mảng self.myWallet chứa các đối tượng mà không phải là danh sách sở hữu các đối tượng, bạn sẽ cần để mã hóa nó cho mình để NSData trước khi lưu, và giải mã khi tải.

Kiểm tra câu trả lời cho số question đó.

+0

Cảm ơn! Tôi đã đi qua câu trả lời tương tự này, tôi đã thử nó và vẫn tồn tại một lỗi xảy ra trong thời gian chạy. Tôi sẽ thử các gợi ý khác ở trên, nơi bạn cũng bình luận :) – Grauzten

4
@implementation Card 

- (void)encodeWithCoder:(NSCoder *)enCoder 
{ 
    [super encodeWithCoder:enCoder]; 
    [enCoder encodeObject:self.name forKey:@"CardName"]; 
    [enCoder encodeInt:self.pin forKey:@"CardPin"]; 
    [enCoder encodeDouble:self.points forKey:@"CardPoints"]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    if(self = [super initWithCoder:aDecoder]) 
    { 
     self.name = [aDecoder decodeObjectForKey:@"CardName"]; 
     self.pin = [aDecoder decodeIntForKey:@"CardPin"]; 
     self.points = [aDecoder decodeDoubleForKey:@"CardPoints"];  
    } 
    return self; 
} 

@end 

Giả sử tên đó thuộc loại NSString, ghim thuộc loại NSInteger và Điểm là loại Đôi bạn có thể sử dụng mã trên trực tiếp trong dự án của mình.

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