Objective c 保留在NSThread中创建的对象
我有以下方法,它是通过调用新线程(使用NSThread)生成的: 我的Objective c 保留在NSThread中创建的对象,objective-c,cocoa,multithreading,memory-management,thread-safety,Objective C,Cocoa,Multithreading,Memory Management,Thread Safety,我有以下方法,它是通过调用新线程(使用NSThread)生成的: 我的doneLoading:方法如下所示: - (void) doneLoading:(NSArray *)obj { myArray = [[NSArray alloc] initWithArray:obj copyItems:NO]; } myArray的内容无效。如何保存myArray的内容,以便以后在我的应用程序中使用 p.S.myArray在类头文件中定义。除了updateFMLs中的内存泄漏之外,您发布的代码
doneLoading:
方法如下所示:
- (void) doneLoading:(NSArray *)obj {
myArray = [[NSArray alloc] initWithArray:obj copyItems:NO];
}
myArray
的内容无效。如何保存myArray的内容,以便以后在我的应用程序中使用
p.S.
myArray
在类头文件中定义。除了updateFMLs
中的内存泄漏之外,您发布的代码看起来不错。您可能在其他地方过度释放了对象。我猜它会出现在任何进行SomeArrayRomanotherProcess
的地方。除了updateFMLs
中的内存泄漏之外,您发布的代码看起来不错。您可能在其他地方过度释放了对象。我猜它会出现在执行SomeArrayRomanotherProcess
的任何地方。如果您的后台线程做了一些工作,并且需要将NSArray
传递给主线程,那么doneLoading需要做的就是:
-(void)doneLoading:(NSArray *)obj
{
[myArray release]; // release the previous array and its objects
myArray = [obj retain];
// now use myArray, refresh tables, etc.
}
(可能)不需要再制作一个数组副本,这可能是根本的问题。您还应该在调用performSelector
后调用[temp release]
,因为该调用的参数已经保留
如果myArray
的内容以某种方式变得有效,那么它们将在某处被双重释放myArray
将保留添加到其中的所有对象。您提到myArray
本身将变得无效,因此请尝试使用此模式重写您的后台线程和doneLoading方法
最后,您应该使用
[pool drain]
来代替[pool release]
如果您的后台线程做了一些工作,并且需要将NSArray
传递给主线程,那么所有doneLoading需要做的就是:
-(void)doneLoading:(NSArray *)obj
{
[myArray release]; // release the previous array and its objects
myArray = [obj retain];
// now use myArray, refresh tables, etc.
}
(可能)不需要再制作一个数组副本,这可能是根本的问题。您还应该在调用performSelector
后调用[temp release]
,因为该调用的参数已经保留
如果myArray
的内容以某种方式变得有效,那么它们将在某处被双重释放myArray
将保留添加到其中的所有对象。您提到myArray
本身将变得无效,因此请尝试使用此模式重写您的后台线程和doneLoading方法
最后,您应该使用
[pool drain]
代替[pool release]
上述选项的替代方法是在标头中将myArray声明为原子属性
@property (atomic,retain) NSArray *myArray;
然后在updateFMLs中,您应该能够从辅助线程简单地调用setter。显然,只有当您愿意为原子属性支付性能惩罚时,这才有效
- (void) updateFMLs {
NSAutoreleasePool *pool - [[NSAutoreleasePool alloc] init];
NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess];
[self setMyArray:temp];
[temp release];
[pool drain];
}
上述选项的另一种选择是将myArray声明为标头中的原子属性
@property (atomic,retain) NSArray *myArray;
然后在updateFMLs中,您应该能够从辅助线程简单地调用setter。显然,只有当您愿意为原子属性支付性能惩罚时,这才有效
- (void) updateFMLs {
NSAutoreleasePool *pool - [[NSAutoreleasePool alloc] init];
NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess];
[self setMyArray:temp];
[temp release];
[pool drain];
}
你说的“变得无效”是什么意思。他们被释放了吗?顺便说一句,你正在泄漏“临时”数组。您分配了一个数组(+1 retain count),但您从未释放它。是的,在我进行DoneLoad时,它们似乎会被释放…即使DoneLoad中除了上面显示的行之外,没有任何内容以任何方式更改myArray,用线程相关的标记重新标记,并删除不太相关的iPhone标记。您所说的“变得无效”是什么意思。他们被释放了吗?顺便说一句,你正在泄漏“临时”数组。您分配了一个数组(+1 retain count),但您从未释放它。是的,在我进行doneLoading时,它们似乎会被释放…即使doneLoading中除了上面显示的行之外,没有任何内容会以任何方式更改myArray,并用线程相关的标记重新标记,当我调试updateFMLs时,temp被正确的数据填充。当它被传递到doneLoading,然后变得无效时,这让我很困惑……当池在updateFMLs中释放时,它们可能会被释放,这将发生在调用DoneLoad之前。如果是这种情况,那么您必须找到错误地释放它的地方,并删除该释放。Tom Dalling:但是数组中的对象被数组保留,他正在泄漏(它没有自动释放)。如果他修复了泄漏,那么这将成为一个问题,但这不是所示代码中的问题。我认为这类似于[[[MyItem new]autorelease]autorelease],它将释放对象,即使泄漏的数组对它们有保留。当我调试updateFMLs时,temp填充了正确的数据。当它被传递到doneLoading,然后变得无效时,这让我很困惑……当池在updateFMLs中释放时,它们可能会被释放,这将发生在调用DoneLoad之前。如果是这种情况,那么您必须找到错误地释放它的地方,并删除该释放。Tom Dalling:但是数组中的对象被数组保留,他正在泄漏(它没有自动释放)。如果他修复了漏洞,那么这将成为一个问题,但这不是所示代码中的问题这将解除对象的分配,即使泄漏的数组有保留。如果另一个线程在您的
发布
消息和分配新数组之间使用myArray
,会发生什么情况?可能(根据问题)他只在主线程上使用myArray
。他的后台线程似乎建立了一个新模型,然后需要将其传递给主线程进行处理。他的问题更多的是关于内存管理而不是线程同步。解决