【问题标题】:NSMutableArray not saved NSUserDefaultNSMutableArray 未保存 NSUserDefault
【发布时间】:2013-05-13 10:05:19
【问题描述】:

我正在尝试使用 NSUSerDefault 保存 NSMutableArray,然后打开该数组。 这里有一些代码:

-(IBAction)btnSave{    
Class *aClass = [[Class alloc]init];    
aClass.idClass=@"aaaxxx";    
aClass.nameClass=@"hello";
[myArray addObject:aClass];
NSUserDefaults *arrayDefault=[NSUserDefaults standardUserDefaults];
[arrayDefault setObject:myArray forKey:@"savedArray"];
[arrayDefault synchronize]; 
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    myArray=[[NSMutableArray alloc]init];

    NSMutableArray *savedArray=[[NSUserDefaults standardUserDefaults]objectForKey:@"savedArray"];
    if(savedArray!=NULL){
        myArray=savedArray;
        [tableView reloadData];
    }
    // Do any additional setup after loading the view from its nib.
}

当我编译并按下按钮时,这是我在日志输出中看到的内容:

[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '(
    "<Class: 0x8452b40>"
)' of class '__NSArrayM'.  Note that dictionaries and arrays in property lists must also contain only property values

很明显,当我重新打开视图时,数组没有加载。 有什么帮助吗?

【问题讨论】:

    标签: objective-c xcode nsmutablearray nsuserdefaults


    【解决方案1】:

    NSUserDefaults 只允许在其中存储 Premitive DataTypes。如果你想存储你的自定义类 Object 然后使用下面的代码,更多细节参考这个IOS Documentation

    //create an array with your custom class objects
    
    Class *aClass = [[Class alloc]init];
    aClass.idClass=@"aaaxxx";
    aClass.nameClass=@"hello";
    
    [myArray addObject:aClass];
    
    //convert your array to `NSData` object using `NSKeyedArchiver`    
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myArray];
    
    //store it to `NSUserDefaults`
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"myArray"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    //convert your stored Object back to `NSData` using `NSKeyedUnarchiver`    
    NSData *storedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myArray"];
    NSArray *storedArr = [NSArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:storedData]];
    
    NSLog(@"%@",storedArr[0]);
    

    【讨论】:

    • 有效!!!我只改变了一件事:在“viewDidLoad”上我放了: if(storedData!=NULL){ myArray = [NSArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:storedData]]; }
    • yes 检查数组是否已经存储在 UserDefaults 中。干得好。
    • 好的,它正在工作......但没有那么好。问题是当我想向加载的数组添加一个新对象时。当我创建新对象并使用 [myArray addObject:newObj] 将其添加到数组中时,我需要重新加载 TableView 并且当我到达“cellForRowAtIndexPath”的部分时: if (cell == nil) { [[NSBundle mainBundle] loadNibNamed:sLoadNibNamed owner:self options:NULL];单元格 = [自我 typeNibLoadCell:aEquipaggio.idMembro];应用程序进入异常:[UITextFieldRoundedRectBackgroundView idMembro]: unrecognized selector sent to instance
    • 它可能不会在您的 NSUserDefaults 中更新,如果您忘记同步并重新加载您的 NSArray,那么它会发生。我发布的代码仅供参考,您必须根据您的应用要求进行更改。
    【解决方案2】:

    首先你在你的对象类中实现 NSCoding。为了保存/加载这些对象的 NSMutableArray,您可以执行以下操作:

    - (void) loadArray {
        //Loading the NSMutableArray
        NSData *arrayData = [[NSUserDefaults standardUserDefaults] objectForKey:@"ArrayKey"];
        myArray = [NSKeyedUnarchiver arrayData];
    }
    
    -(void) saveArray {
        //Saving the NSMutableArray
        NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:myArray];
        [[NSUserDefaults standardUserDefaults] setObject:arrayData forKey:@"ArrayKey"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    

    有关更多信息,我建议查看更长的教程。例如 Ray Wenderlich 的 How to Save your App Data with NSCoding And NSFileManager 就是一个很好的。

    【讨论】:

      【解决方案3】:

      您需要在模型对象Class 中实现 NSCoding 协议。需要对非标准数据进行序列化和反序列化到NSUserDefaults

      现在您可以使用NSKeyedArchiver 将对象转换为数据并存储在 userDefaults 中。使用NSKeyedUnarchiver 将数据从默认值转换回对象。

      //h file
      @interface Class : NSObject<NSCoding>
      
      @property (nonatomic, copy) NSString *idClass;
      @property (nonatomic, copy) NSString *nameClass;
      
      
      //m File
      
      - (void)encodeWithCoder:(NSCoder *)aCoder{
      
          [aCoder encodeObject:self.idClass forKey:@"IDClass"];
          [aCoder encodeObject:self.nameClass forKey:@"NameClass"];
      
      }
      
      - (id)initWithCoder:(NSCoder *)aDecoder{
      
          self = [super init];
      
          if (self) {
              self.idClass = [aDecoder decodeObjectForKey:@"IDClass"];
              self.nameClass = [aDecoder decodeObjectForKey:@"NameClass"];
          }
      
          return self;
      }
      

      实施 NSCoding 后,您可以将它们归档以存储为 userDefaults 中的数据

      //Saving array
      Class *aClass = [[Class alloc]init];    
      aClass.idClass=@"aaaxxx";    
      aClass.nameClass=@"hello";
      
      [myArray addObject:aClass];
      
      NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myArray];
      
      NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
      [defaults setObject:data forKey:@"savedArray"];
      [defaults synchronize]; 
      
      //Retrieving 
      
      NSData *data = [defaults objectForKey:@"savedArray"];
      NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
      

      【讨论】:

      • @gabboSonc 更新了我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多