Ios 从plist读取的空NSMutableArray成为不可变对象
将空NSMutableArray写入磁盘,然后将其读回,它将成为不可变对象。Ios 从plist读取的空NSMutableArray成为不可变对象,ios,iphone,objective-c,Ios,Iphone,Objective C,将空NSMutableArray写入磁盘,然后将其读回,它将成为不可变对象。 但是,如果NSMutableArray不是空的,则不会为空。怎么解释呢? 代码如下: NSMutableArray *testItems1 = [NSMutableArray array]; NSMutableDictionary *testList1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:testItems1, @"list_items", @"lis
但是,如果NSMutableArray不是空的,则不会为空。怎么解释呢?
代码如下:
NSMutableArray *testItems1 = [NSMutableArray array];
NSMutableDictionary *testList1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:testItems1, @"list_items", @"list1", @"list_name", nil];
NSMutableArray *testItems2 = [NSMutableArray arrayWithObjects:@"item11", @"item22", nil];
NSMutableDictionary *testList2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:testItems2, @"list_items", @"list2", @"list_name", nil];
NSMutableArray *testLists = [NSMutableArray arrayWithObjects:testList1, testList2, nil];
[testLists writeToFile:@"/tmp/testLists" atomically:YES];
NSMutableArray *testReadLists = [NSMutableArray array];
[testReadLists setArray:[NSArray arrayWithContentsOfFile:@"/tmp/testLists"]];
NSMutableDictionary *testReadList = [testReadLists objectAtIndex:0];
NSMutableArray *testReadItems = [testReadList objectForKey:@"list_items"];
[testReadItems addObject:@"item3"]; // Crashes here: "*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'"
这两行代码:
NSMutableArray *testReadLists = [NSMutableArray array];
[testReadLists setArray:[NSArray arrayWithContentsOfFile:@"/tmp/testLists"]];
为您提供不可变对象的可变数组。您可以从testreadlist
中添加和删除对象,但从该数组(最初从plist加载)获得的所有内容都是不可变的
更新-我正要发布有关解决方案的信息,但Vivek的回答描述了我要说的内容。这两行代码:
NSMutableArray *testReadLists = [NSMutableArray array];
[testReadLists setArray:[NSArray arrayWithContentsOfFile:@"/tmp/testLists"]];
为您提供不可变对象的可变数组。您可以从testreadlist
中添加和删除对象,但从该数组(最初从plist加载)获得的所有内容都是不可变的
更新-我正要发布有关解决方案的信息,但Vivek的回答描述了我要说的内容。我自己还没有测试过,但您可能想先将plist读入NSData,然后通过执行
+[NSPropertyListSerialization propertyListWithData:options:format:error:
获得实际数组,在选项参数(apple doc)中指定nsPropertyListMetableContainers
注意,这将为您提供可变容器的完整层次结构(包含NSMutableDictionary等的NSMutableArray)。如果您只需要层次结构中某一特定级别的NSMutableArray,那么其他发布的解决方案/注释可能是更合适的解决方案。我自己还没有测试过这一点,但您可能希望首先将plist读入NSData,然后通过执行
+[NSPropertyListSerialization propertyListWithData:选项:格式:错误:
,在选项参数(apple文档)中指定NSPropertyListMutableContainers
注意:这将为您提供可变容器的完整层次结构(包含NSMutableDictionary的NSMutableArray,等等)。如果您只需要层次结构中某一特定级别的NSMutableArray,则其他发布的解决方案/注释可能是更合适的解决方案。直接从属性列表读取的对象始终是不可变的。您可以从它们创建可变对象,但对象本身是不可变的。这些行是问题所在lem:
NSMutableDictionary *testReadList = [testReadLists objectAtIndex:0];
NSMutableArray *testReadItems = [testReadList objectForKey:@"list_items"];
testReadList
是可变数组testReadList
中的第一个对象,但是该对象本身仍然是不可变的,尽管testReadList
的声明类型是NSMutable*
。同样,从objectForKey:
调用返回的对象是NSArray
的实例>即使将其分配给声明为NSMutableArray*
的testReadItems
,也可以通过在添加新项之前创建可变副本来避免问题:
NSMutableArray *testReadItems = [[testReadList objectForKey:@"list_items"] mutableCopy];
直接从属性列表读取的对象始终是不可变的。您可以从它们创建可变对象,但对象本身是不可变的。问题在于:
NSMutableDictionary *testReadList = [testReadLists objectAtIndex:0];
NSMutableArray *testReadItems = [testReadList objectForKey:@"list_items"];
testReadList
是可变数组testReadList
中的第一个对象,但是该对象本身仍然是不可变的,尽管testReadList
的声明类型是NSMutable*
。同样,从objectForKey:
调用返回的对象是NSArray
的实例>即使将其分配给声明为NSMutableArray*
的testReadItems
,也可以通过在添加新项之前创建可变副本来避免问题:
NSMutableArray *testReadItems = [[testReadList objectForKey:@"list_items"] mutableCopy];
以JSON格式写入数据。使用NSJSONSerialization进行读取,指定
NSJSONReadingMutableContainers
选项。仅供参考-到/tmp
的路径仅在模拟器或越狱iOS设备中有效。不要在“real”中使用此类路径代码。以JSON格式写入数据。使用NSJSONSerialization读回,指定NSJSONReadingMutableContainers
选项。仅供参考-到/tmp
的路径仅在模拟器或越狱iOS设备中有效。不要在“真实”代码中使用此类路径。[[NSArray arrayWithContentsOfFile:@”/tmp/testlist]mutableCopy]
更容易为什么不仅仅是[NSMutableArrayWithContentsOfFile:@/tmp/TestList”];
?[NSArrayWithContentsOfFile:@/tmp/TestList”]mutableCopy]
更容易为什么不仅仅是[NSMutableArrayWithContentsOfFile:@/tmp/TestList”];
[NSMutableArrayWithContentsOfFile:file]呢?我更改了此选项,现在可以使用了。我已测试了3个级别(NSMutableDictionary包含NSMutableDictionary包含NSMutableArray包含NSMutableArray)使用[NSMutableArray arrayWithContentsOfFile:file]读取的列表数据。NSMutableArray中最内部的是可变的。[NSMutableArrayWithContentsOfFile:]它还提供了可变容器的完整层次结构,比读取NSData并使用+[NSPropertyListSerialization propertyListWithData:options:format:error:]更简单[NSMutableArray arrayWithContentsOfFile:file]怎么样?我改成了这个,现在它可以工作了我已经测试了3个级别(NSMutableDictionary包含NSMutableDictionary包含NSMutableArray)使用[NSMutableArray arrayWithContentsOfFile:file]读取列表数据。NSMutableArray内部的大部分是可变的。[NSMutableArrayWithContentsOfFile:]还提供了可变容器的完整层次结构,比读取NSData和使用更简单+[NSPropertyListSerialization propertyListWithData:选项:格式:错误:]