【问题标题】:When NSDictionary is added to array, it replaces the previous dictionary当 NSDictionary 添加到数组时,它会替换之前的字典
【发布时间】:2012-01-18 12:14:01
【问题描述】:

更新:找出一些东西并更改了代码。

当我将 NSDictionary 添加到我的数组时,它突然替换了我上次添加的上一个字典。我不知道为什么会这样。我正在使用 plist 作为数据存储。

我收到如下错误消息:

线程 1:程序接收信号:“EXC_BAD_ACCESS”。

初始化

-(id)init{
    self=[super init];
    if(self){
        dbArray = [[NSMutableArray alloc] init];
    }
    return self;
}

添加新项目。

-(void)addNewItem:(NSString *)aString
{
    // Creates a mutable dictionary with a anonymous string under the NAME key.
    NSDictionary *newString = [[NSDictionary alloc] initWithObjectsAndKeys:aString,@"name", nil];

    // Adds the new string to empty dbArray.
    [dbArray addObject:(newString)];
    NSLog(@"[add]:Added anonymous string to dbArray, under name key.");

    // Writes the current dbArray (with the dict) to plist and releases retain counts.
    [self writeItem];
    [newString release];
}

我查看数据的方法。

-(void)viewData
{
    // View data from the created plist file in the Documents directory.

    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *finalPath = [documentsDirectory stringByAppendingPathComponent:@"data.plist"];

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:finalPath]) {
        self.dbArray = [NSMutableArray arrayWithContentsOfFile:finalPath];
    }
    else {
        self.dbArray = [NSMutableArray array];
    }
}

【问题讨论】:

  • 您一直在写入文件新数组。 Mb 你应该删除self.dbArray = [[NSMutableArray alloc] init]; 。您将附加您的数组并正确重写它。
  • 也许您的addNewItem 方法不只是添加。看起来您正在分配和初始化一个新数组,然后再向它添加新值。这将给出一个只有新值的新数组。
  • @RomanTemchenko 我已经尝试删除 self.dbArray = [[NSMutableArray alloc] init]; 并且当我这样做时它不会将字典保存到数组和 plist 中。
  • @Ravin455 检查dbArray 是否存在于addNewItem: 中。你在addNewItem:之前打电话给viewData吗?
  • @RomanTemchenko 是的,我在addNewItem 之前打电话给viewData

标签: ios arrays plist file-writing nsdocumentdirectory


【解决方案1】:

而不是这个

self.dbArray = [[NSMutableArray alloc] init];

使用这个

if( nil == self.dbArray ) {
  self.dbArray = [[NSMutableArray alloc] init];
}

更新:(基于提供的代码)

  • 您正在使用 DataObject 类的不同实例来显示和保存数据。您的内容被覆盖,因为您在每个实例的初始化期间不从文件中加载数据;要快速解决这个问题,您需要实现 DataObject 类的 init 方法,如下所示:
- (id)init{
    self = [super init];
    if(self){
      [self viewData];
    }
    return self;
}

ViewController 类的 viewDidLoad 中的以下代码会经常使您的应用程序崩溃:

db = [[DataObject alloc] init];
[db viewData];
[db release];

array = [[NSMutableArray alloc] initWithArray:[db dbArray]];

替换为

db = [[DataObject alloc] init];
[db viewData];

array = [[NSMutableArray alloc] initWithArray:[db dbArray]];

仅在 dealloc 实现中调用 [db release]

  • 您可能会遇到的另一个问题是,当您返回主屏幕时不会显示更新的数据;解决这个问题,将以下方法实现添加到您的 ViewController.m 文件中:
- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];

  [db viewData];
  self.array = [NSMutableArray arrayWithArray: db.dbArray];
  [self.tableView reloadData];
}

同样在 AddView.m 中替换以下代码

// Dismiss view and reload tableview.
ViewController *vc = [[ViewController alloc] init];
[self dismissModalViewControllerAnimated:YES];
[vc release];

// Dismiss view and reload tableview.
[self dismissModalViewControllerAnimated:YES];

正如建议:查看有关使用委托以及在对象之间传递对象实例和副本的更多信息。

【讨论】:

  • 如果它仍然替换它,你是否覆盖了你的 dbArray 属性的 getter/setter?
  • 将 NSZombieEnabled 设置为 YES 并确定是什么对象释放导致此崩溃,否则 - 这只是猜测
  • *** -[DataObject dbArray]: message sent to deallocated instance 0x6a5f4e0 这是我将 NSZombieEnabled 设置为 YES 时得到的结果,但这是来自另一个从我的 NSObject 接收消息的控制器。我只使用-(id)init 方法在我的NSObject 中分配了一次,否则我将它保留在我的NSObject 的.h 文件中。
  • 我的视图控制器有这行:array = [[NSMutableArray alloc] initWithArray:[db dbArray]]; 我已将db 声明为 DataObject(NSObject)。
  • 恐怕,我需要看看整个项目才能为您提供帮助
【解决方案2】:

我认为您正在创建一个新数组:

self.dbArray = [[NSMutableArray alloc] init];

您应该在viewDidLoadUIViewController 的初始化上创建dbArray(我假设您在UIViewController 上使用它)

在您的 DataObject 中执行以下操作:

  -(id)init{
    self=[super init];
    if(self){
      self.dbArray = [[NSMutableArray alloc] init];
   }
   return self;
  }

【讨论】:

  • 不,我没有使用UIViewController,而是使用NSObject。所以我可以用什么代替viewDidLoad
  • @Denis 给了你答案,但是当你不需要它们时,我不喜欢使用“Ifs”。我会覆盖您的默认 init 方法,并在那里添加分配。
  • 你的意思是在我的viewData 中我应该用self.dbArray = [[NSMutableArray alloc] initWithContentsOfFile:finalPath]; 替换self.dbArray = [NSMutableArray arrayWithContentsOfFile:finalPath];
  • 不,当您分配 NSObject 时,您会执行以下操作:MyObject *myObject=[MyObject alloc] init] 您应该覆盖您的 init 方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
相关资源
最近更新 更多