【问题标题】:NSMutableArray in NSUserDefaultsNSUserDefaults 中的 NSMutableArray
【发布时间】:2011-07-21 15:45:22
【问题描述】:

我很抱歉我的英语不好,但我试图用最好的词来解释。

当我尝试在 NSUserDefaults 中插入 NSMutableArray 时遇到了一些问题([NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ')

我插入数组的代码如下:

-(void)saveToUserDefaults:(NSMutableArray*)myArray
{
    NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
    NSArray *array = [[NSArray alloc ] initWithArray:myArray];

    if (standardUserDefaults) 
      {
           [standardUserDefaults setObject:array forKey:@"MyArray"];
           [standardUserDefaults synchronize];
      }

}

我检索数组的代码:

-(NSMutableArray*)retrieveFromUserDefaults
 {
     NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
     NSMutableArray *val = [[NSMutableArray alloc]init];

     if (standardUserDefaults) 
             val = [NSMutableArray arrayWithArray:[standardUserDefaults arrayForKey:@"MyArray"]];

     return val;

}

在我的代码中:

NSMutableArray:

  series = [[NSMutableArray alloc]initWithObjects:nil];
 //add some object inf my array...

保存我的 NSMutableArray:

 [self saveToUserDefaults:series];

检索我的 NSMutableArray :

 series = [self retrieveFromUserDefaults];

我认为这不是最好的方法,所以如果有人有想法,它会对我有所帮助。

感谢阅读。

汤米

【问题讨论】:

  • 我能有完整的实现代码吗

标签: iphone ios


【解决方案1】:

只有不可变的NSArrays 可以放入默认值。与其在其中放置 NSMutableArray,不如使用 [NSArray arrayWithArray:] 转换为常规数组并将其放入默认值。

对于检索,检索一个 NSArray,然后使用 [NSMutableArray arrayWithArray:]

【讨论】:

  • 我不能做 NSArray *array = [[NSArray alloc] arrayWithArray:myArray];
  • @tommy arrayWithArray 是一个类方法;不要先调用 alloc 。 [NSArray arrayWithArray:myArray]
  • @tommy:要么那个,要么[[NSArray alloc] initWithArray:myArray]。这两种方式是不等价的——前者产生一个自动释放的对象,第二种方式稍后需要一个release
  • static 是一个 C 关键字,其含义与“非可变”不同,我认为这就是您的意思。我不认为您不能将可变数组存储到 NSUserDefaults。您绝对可以在可变集合上调用 writeToFile:atomically:
  • @bshirley:是的,选词不好。我的意思是“不可变的”。已编辑。
【解决方案2】:

您可以使用以下方法从不可变对象中获取可变对象。它没有经过优化,仅针对 NSArray 和 NSDictionary 实现。

 + (id) GetMutable:(id)input {
    id result;
    if ([input superclass] == [NSArray class] || [input superclass] == [NSMutableArray class]) {
        result = [[NSMutableArray alloc] initWithArray:input copyItems:YES];

        for (int i = 0; i < [(NSMutableArray*)result count]; i++) {
            [(NSMutableArray*)result replaceObjectAtIndex:i withObject:[Globals GetMutable:[(NSMutableArray*)result objectAtIndex:i]]];
        }
    } else  if ([input superclass] == [NSDictionary class] || [input superclass] == [NSMutableDictionary class]) {
        result = [[NSMutableDictionary alloc] initWithDictionary:input copyItems:YES];

        NSArray *keys=[(NSMutableDictionary*)result allKeys];

        for (int i = 0; i < keys.count; i++) {
            [(NSMutableDictionary*)result setObject:[Globals GetMutable:[(NSMutableDictionary*)result objectForKey:[keys objectAtIndex:i]]] forKey:[keys objectAtIndex:i]];
        }

    }
    else {
        return input;
    }
    return result;
}

【讨论】:

    【解决方案3】:

    我希望this 教程对谁期待这个问题的答案有所帮助。

    -(void)saveToUserDefaults:(NSString*)myServerName uname:(NSString*)myUserName 
        pass:(NSString*)myPassword
      {
         NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
    
        if (standardUserDefaults) {
        [standardUserDefaults setObject:myServerName forKey:@"ServerKey"];
        [standardUserDefaults setObject:myUserName forKey:@"UserNameKey"];
        [standardUserDefaults setObject:myPassword forKey:@"PasswordKey"];
        [standardUserDefaults synchronize];
       }
    }
    -(NSArray*)retrieveFromUserDefaults
    {
        NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
        NSString *serverName = nil;
        NSString *userName = nil;
        NSString *password = nil;
        if (standardUserDefaults)
        serverName = [standardUserDefaults objectForKey:@"ServerKey"];
        userName = [standardUserDefaults objectForKey:@"UserNameKey"];
        password = [standardUserDefaults objectForKey:@"PasswordKey"];
    
        NSArray* credentials = [NSArray arrayWithObjects:serverName,userName,password, nil];
        return credentials;
    }
    

    传递值

    [self saveToUserDefaults:serverVariable uname:usernameVariable pass:passVariable];
    

    获取价值

    NSArray *result=[self retrieveFromUserDefaults];
    

    编码愉快!!!

    【讨论】:

      【解决方案4】:

      您的数组内容只能通过 plist 有效对象:(NSStringNSNumberNSDateNSDataNSArrayNSDictionary 对象)。

      请参阅 NSUserDefaults setObject:forKey:What is a Property List? 的文档

      【讨论】:

        【解决方案5】:

        您的代码需要大量清理。这是访问标准用户默认值的简单而正确的方法:

        1. 您传递给 save 方法的值不需要是可变的,尽管它可以。但是因为你没有在你的方法中改变它,所以它没有必要是可变的。它必须不为零,您将在保存之前检查它:

          -(void)saveToUserDefaults:(NSArray*)myArray { 如果(我的数组){ NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults]; myDefaults[@"myArray"] = myArray; } }

        2. 标准用户默认只返回非可变对象,您可以使用“mutableCopy”方法将其转换为可变副本:

          -(NSMutableArray*)retrieveFromUserDefaults { NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults]; NSMutableArray *val = [[NSMutableArray alloc] init]; val = [myDefaults[@"MyArray"] mutableCopy]; 返回值; }

        【讨论】:

        • 对搞砸的代码块格式表示歉意。 ctrl-K、cmd-K 或 {} 都不适合我。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-04-16
        • 1970-01-01
        • 1970-01-01
        • 2013-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多