我已经读了几个小时,搜索过苹果的doc,stackoverflow,无法理解我做错了什么......
当我在UITableViewController上使用来自XML plist的数据时:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:@"arrayofstrings"
ofType:@"plist"];
NSData *myData = [NSData dataWithContentsOfFile:path];
NSString *error;
NSPropertyListFormat format;
myArray = [NSPropertyListSerialization propertyListFromData:myData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&error];
}
我的tableview显示第一个可见的行很好但在尝试滚动时崩溃。
当我使用类似的东西代替XML数据时,它不会发生:
- (void)viewDidLoad
{
[super viewDidLoad];
myArray = [[NSArray alloc] initWithObjects:@"thing1", @"thing2", @"thing3", @"thing4", @"thing5",@"thing6", @"thing7", @"thing8", @"thing9", @"thing10",
@"thing11",@"thing12", @"thing13", @"thing14", nil];
}
这样,tableview滚动就好了。什么是我的问题?!是否应该以任何其他方式将plist转换为数组?
答案 0 :(得分:0)
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:@"arrayofstrings"
ofType:@"plist"];
NSData *myData = [NSData dataWithContentsOfFile:path];
NSString *error;
NSPropertyListFormat format;
myArray = [[NSPropertyListSerialization propertyListFromData:myData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&error] retain];
}
propertyListFromData:mutabilityOption:format:errorDescription
的返回值为autorelease
d。确保你调用retain,这样它就不会在当前运行循环结束时从你下面释放出来。
第二种方法有效,因为使用NSArray
创建alloc/init
会使数组的保留计数为1。
答案 1 :(得分:0)
问题在于,在第一种情况下,您对[NSPropertyListSerialization propertyListFromData:
的调用会返回一个没有保留计数的NSArray(注意该方法在名称中没有alloc,new或copy) - 然后你不要保留这个NSArray。因此,该阵列很快就会被释放,并且您的代码崩溃,试图访问垃圾内存。
在第二种情况下,您正在使用alloc
创建一个NSArray - 这将返回一个保留计数为1的NSArray,这意味着它不会被释放(直到在某个时刻调用某个版本)。 / p>
要解决此问题,在第一种情况下,您需要按如下方式分配数组:
self.myArray = ...
self.
是这里的关键部分(假设你已将myArray属性声明为retain
)。
有大量资源和blog posts可用于内存管理。