在一个线程中创建并在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】:

您的问题很难理解,因为您谈论的是这个对象、那个对象、另一个对象,并且使用了无意义的名称,例如 myClassanotherClassmethod。目前尚不清楚您打算释放哪个对象以及哪个对象被报告为泄漏。

无论如何,多线程不会给引用计数增加任何特殊的复杂性。当然,您的两个对象 myClassanotherClass 不是短期对象。因此,如果您使用自动释放,如果所有自动释放都已执行,请确保引用计数器不会变为 0。

method 中释放 myClassanotherClass 或两者都可以。

您没有显示很多代码。但是你显示的没问题。

【讨论】:

对不起,如果我不清楚。我可以通过其他方式调用类和方法,但概念是我在方法中创建一个对象,然后使用 performSelectorOnMainThread 传递它。问题是,如何正确释放该对象?如果我没有误解另一个答案,那就是我所缺少的: performSelectorOnMainThread 保留它并在完成后释放。谢谢!

以上是关于在一个线程中创建并在objective-C中传递给另一个线程的自动释放对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C 调用在 MATLAB 中创建并在 C 中编译的函数?

Objective-C:在一个线程中分配并在另一个线程中释放

如何在Windows系统中创建并使用Git仓库

在 SwiftUI DocumentGroup macOS 中创建并打开一个新文档

Libev C++ 无法停止多线程应用程序中的动态循环

在子数组列表中创建并查找最大值