【问题标题】:Working with NSMutableArray and NSUserDefaults使用 NSMutableArray 和 NSUserDefaults
【发布时间】:2012-06-14 17:10:16
【问题描述】:

我正在尝试从 NSUserDefaults 创建一个 NSMutableArray,以便稍后添加/删除和编辑它

我的代码是

- (void)viewDidLoad {
[super viewDidLoad];

NSUserDefaults *ArrayTable = [NSUserDefaults standardUserDefaults];
[ArrayTable setObject:@"One" forKey:@"myArray"];
[ArrayTable setObject:@"Two" forKey:@"myArray"];
[ArrayTable setObject:@"Three" forKey:@"myArray"];
[ArrayTable setObject:@"Four" forKey:@"myArray"];
[ArrayTable setObject:@"Five" forKey:@"myArray"];
[ArrayTable synchronize];

NSMutableArray *array = [[NSMutableArray alloc] init];
array = [ArrayTable objectForKey:@"myArray"];
}


- (void)viewDidUnload
{
    [super viewDidUnload];
}

#pragma mark - Table View

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [array count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    cell.textLabel.text = [array objectAtIndex:indexPath.row];
    return cell;
}

当我构建并运行时,什么都没有显示

我用谷歌搜索了它,但没有任何帮助,我确定我不明白该怎么做

我需要的是构建一个包含空数据的tableview的应用程序,使用将填充数据添加/删除/编辑

谁能帮我解释一下

提前谢谢你

【问题讨论】:

  • 你到底想做什么?您正在询问有关 NSUserDefaults 的问题,但从您的 cmets 看来,您根本不需要这些首选项。因此,请描述您要解决的实际最终用户问题。
  • 我需要构建一个包含空数据的tableview的应用程序,使用将填写数据添加/删除/编辑@abarnert
  • 所以它与存储在 NSUserDefaults 中的首选项完全没有关系?您可能需要编辑问题。

标签: objective-c xcode


【解决方案1】:

首先,您将用户默认值中的数组分配给名为array 的局部变量。假设你有一个这个类的属性也叫array,这个本地赋值会掩盖它。如果没有,当您尝试在字符串上调用 -count 时,您会崩溃。

NSUserDefaults 对象是一个字典。每次调用-setObject:forKey: 时,实际上是在替换 之前为该键设置的对象。因此,在您对-setObject:forKey: 的一系列调用结束时,结果值为NSString 五个

您不能真正将可变对象存储在NSUserDefaults 中,而是在将其分配给局部变量或 ivar 时获取该对象的可变副本。要获得您可能期望的行为,您应该执行以下操作:

- (void)viewDidLoad
{
  // Create the array template and store it in NSUserDefaults
  NSArray* arrayTemplate = [NSArray arrayWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil];
  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
  [defaults setObject:arrayTemplate forKey:@"myArray"];
  [defaults synchronize];

  // Retrieve a mutable copy of the array from user defaults and assign it to the
  // the property 'array' <- note, this should be an NSMutableArray
  self.array = [[defaults objectForKey:@"myArray"] mutableCopy]; // if not using arc, autorelease this here
}

使用该示例代码,它应该按照您预期的方式运行,您可以继续。显然,在-viewDidLoad 中设置数组然后立即读取可变副本是没有意义的。要记住的关键是-setObject:forKey: 将始终替换 已为该键设置的任何对象。它不会添加元素或类似的东西。

【讨论】:

    【解决方案2】:

    您的问题是您将一堆字符串都设置为同一个键:

    [ArrayTable setObject:@"yourvalue" forKey:@"myArray"];
    

    只是不断覆盖您的最后一个值。为了将数组保存为默认值,您必须以另一种方式进行。这个问题可能会对你有所帮助:array to defaults

    【讨论】:

      【解决方案3】:

      由于您实际上并不希望与 NSUserDefaults 的内容有任何关系,因此您只是在询问如何初始化一个可变数组。以下是您尝试做的事情的方法:

      NSMutableArray *array = [[NSMutableArray alloc] init];
      [array addObject:@"One"];
      [array addObject:@"Two"];
      [array addObject:@"Three"];
      [array addObject:@"Four"];
      [array addObject:@"Five"];
      

      或者,更简单地说:

      NSMutableArray *array = [NSMutableArray arrayWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil];
      

      (这些并不完全相同。如果您使用 MRC,第一个创建一个您拥有的数组并且必须手动释放,而第二个创建一个自动释放的数组。如果您不了解其中的区别,第二个更好,直到你学会,但很快你应该去学习。)

      如果你想知道为什么你所做的没有奏效,这里是:

      NSUserDefaults *ArrayTable = [NSUserDefaults standardUserDefaults];
      

      这里你复制的是一个 NSUserDefaults 对象,它不是一个数组,也不是一个表;它是用户和系统偏好的包装器,就像具有额外功能的字典一样。

      [ArrayTable setObject:@"One" forKey:@"myArray"];
      

      此行将名为“myArray”的首选项添加到您的应用程序的用户域首选项中,其值为“One”。

      [ArrayTable setObject:@"Two" forKey:@"myArray"];
      [ArrayTable setObject:@"Three" forKey:@"myArray"];
      [ArrayTable setObject:@"Four" forKey:@"myArray"];
      [ArrayTable setObject:@"Five" forKey:@"myArray"];
      

      这些行反复更改“myArray”首选项的值,以“Five”结尾。

      [ArrayTable synchronize];
      

      这可确保您的偏好已保存到磁盘。

      NSMutableArray *array = [[NSMutableArray alloc] init];
      

      这会创建一个新的可变数组并将其存储在变量“array”中。

      array = [ArrayTable objectForKey:@"myArray"];
      

      这会从您的偏好中获取“五”字符串并将其存储到变量“数组”中。

      这意味着您现在失去了对实际数组的唯一引用。

      这也意味着变量的静态类型不再匹配动态类型。当您稍后调用 [array count] 或 [array objectAtIndex:n] 时,您会将这些消息发送到字符串,而不是数组,因此您可能会遇到异常或其他意外行为。 (嗯,几乎可以保证无论你得到什么都会出乎意料,因为你认为你正在与一个由 5 个对象组成的数组而不是一个字符串交谈。)

      【讨论】:

        【解决方案4】:

        创建数组并将其添加到用户默认值。

        - (void)viewDidLoad {
        //...
        NSArray * tmpArray = [NSArray arrayWithObjects:@"One",@"Two",@"Three",@"Four", @"Five", nil];
        
        NSUserDefaults *ArrayTable = [NSUserDefaults standardUserDefaults];
        [ArrayTable setObject:tmpArray forKey:@"myArray"];
        [ArrayTable synchronize];
        
        array = [[ArrayTable objectForKey:@"myArray"] mutableCopy]; 
        // array has to be an ivar of your viewcontroller to access it outside of viewDidLoad
        // define in your header like @property (nonatomic, strong) NSMutableArray * array;
        // with @synthesize array; in the implementation
        

        }

        【讨论】:

        • 我想从 NSUserDefault 创建数组,而不是保存数组中的用户默认值
        • 我想你的意思是@synthesize,不是吗?
        • no :) ,我想要的是使用 tableview 构建一个应用程序,用户可以从表中添加/编辑和删除数据,所以我虽然方法是使用 nsuserdefaults。如果还有其他方法可以请您解释一下
        • @H.aLFaRSi 在应用程序中,您应该使用数组中的数据,然后在内容更改时将该数组保存到 userdefaults。如果你对持久化用户数据很认真,你应该看看 coredata。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-14
        相关资源
        最近更新 更多