我有以下方法,它是通过调用新线程(使用NSThread)产生的:
- (void) updateFMLs {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess];
[self performSelectorOnMainThread:@selector(doneLoading:) withObject:temp waitUntilDone:NO];
[pool release];
}
我的doneLoading:
方法如下所示:
- (void) doneLoading:(NSArray *)obj {
myArray = [[NSArray alloc] initWithArray:obj copyItems:NO];
}
myArray
的内容无效。如何保留myArray
的内容,以便稍后在我的应用中使用它们?
P.S。 myArray
在类头文件中定义。
答案 0 :(得分:1)
如果你的后台线程做了一些工作并且需要将NSArray
“传递”到你的主线程,那么所有doneLoading需要做的是:
-(void)doneLoading:(NSArray *)obj
{
[myArray release]; // release the previous array and its objects
myArray = [obj retain];
// now use myArray, refresh tables, etc.
}
(可能)不需要制作阵列的另一个副本,这可能是潜在的问题。您应该在[temp release]
电话后致电performSelector
,因为已经保留了对此的论据。
如果myArray
的内容以某种方式变得有效,那么它们会在某处被双重释放。 myArray
将保留添加到其中的所有对象。您提到myArray
本身变得无效,因此请尝试使用此模式重写后台线程和doneLoading方法。
最后,您应该使用[pool drain]
代替[pool release]
。
答案 1 :(得分:0)
除了updateFMLs
中的内存泄漏之外,您发布的代码看起来很好。您可能在其他地方过度释放对象。我猜这将是someArrayFromAnotherProcess
的所在地。
答案 2 :(得分:0)
上述选项的替代方法是将myArray声明为标题
中的原子属性@property (atomic,retain) NSArray *myArray;
然后在updateFML中你应该能够简单地从辅助线程调用setter。显然,只有当你愿意支付原子属性的性能损失时,这才有效。
- (void) updateFMLs {
NSAutoreleasePool *pool - [[NSAutoreleasePool alloc] init];
NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess];
[self setMyArray:temp];
[temp release];
[pool drain];
}