在一个线程中创建并在objective-C中传递给另一个线程的自动释放对象
Posted
技术标签:
【中文标题】在一个线程中创建并在objective-C中传递给另一个线程的自动释放对象【英文标题】:Autoreleasing objects created in a thread and passed to another in objective-C 【发布时间】:2011-01-08 10:17:20 【问题描述】:我有一个对象的方法,它创建对象然后传递给另一个线程中另一个对象的方法,如下所示:
MyClass* myClass = [[MyClass alloc] init];
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];
在方法中,我立即保留对象,假设它会被创建者以某种方式释放。我的问题是:如何让 MyClass 正确释放该对象?这是正确的方法吗?
我的解决方案是在方法中手动释放对象。无论如何,我看到泄漏分析器仍然将其识别为泄漏,并且似乎不是 Apple 推荐的,因为所有者有责任释放该对象。
你能解释一下处理这种情况的正确方法吗?谢谢!
【问题讨论】:
哎呀,对不起,我忘记了一个重要的元素:执行我报告的指令的线程不是 Cocoa 线程。我使用 POSIX 线程创建了它。 Cocoa 线程和 POSIX 线程没有区别。但请确保在线程开始时创建一个自动释放池。 我读到还需要创建至少一个 NSThread 才能使用 NSAutoreleasePools。 【参考方案1】:我不完全理解您想要实现的目标,但总的来说:
您不必担心谁以及何时释放/解除分配对象。相反,只需确保在 您(您的单个对象或方法)开始需要它时保留它,并在 您 不再需要它时释放它(或自动释放它,在在这种情况下,它将在您调用 autorelease 的线程上释放)。
这正是performSelectorOnMainThread:withObject:waitUntilDone:
的工作方式。来自documentation:
此方法保留接收者和 arg 参数,直到执行选择器之后。
它会在需要他们完成工作时保留他们。
简而言之,创建对象并将它们发送到另一个线程的方法应该是:
MyClass* myClass = [[MyClass alloc] init]; // retained, will need it for performSelector
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];
[myClass release]; // no longer needing it.
或
MyClass* myClass = [[[MyClass alloc] init] autorelease]; // will be released automatically, but guaranteed to be retained until this method returns
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];
你现在拥有它的方式是内存泄漏。
接收方式:
如果它仅在内部使用该对象,则不必保留它,因为performSelector
会“直到执行后”(方法返回)。
如果以后需要它,则应将其分配给保留它的属性。
【讨论】:
我认为这正是我所需要的:performSelectorOnMainThread 保留它并在完成后释放它。这就是我所需要的,因为现在我可以按照您所说的在 performSelectorOnMainThread 之后释放,确保在仍然使用它时不会释放它。我希望我理解正确!谢谢! 该文档不再包含有关-performSelectorOnMainThread:withObject:waitUntilDone:
的内存管理的信息。谢谢你的回答。【参考方案2】:
您的问题很难理解,因为您谈论的是这个对象、那个对象、另一个对象,并且使用了无意义的名称,例如 myClass、anotherClass 和 method。目前尚不清楚您打算释放哪个对象以及哪个对象被报告为泄漏。
无论如何,多线程不会给引用计数增加任何特殊的复杂性。当然,您的两个对象 myClass 和 anotherClass 不是短期对象。因此,如果您使用自动释放,如果所有自动释放都已执行,请确保引用计数器不会变为 0。
在 method 中释放 myClass 或 anotherClass 或两者都可以。
您没有显示很多代码。但是你显示的没问题。
【讨论】:
对不起,如果我不清楚。我可以通过其他方式调用类和方法,但概念是我在方法中创建一个对象,然后使用 performSelectorOnMainThread 传递它。问题是,如何正确释放该对象?如果我没有误解另一个答案,那就是我所缺少的: performSelectorOnMainThread 保留它并在完成后释放。谢谢!以上是关于在一个线程中创建并在objective-C中传递给另一个线程的自动释放对象的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C 调用在 MATLAB 中创建并在 C 中编译的函数?
Objective-C:在一个线程中分配并在另一个线程中释放