在 Objective-C 中自动释放在线程中创建并传递给另一个线程的对象

发布于 2024-10-11 03:54:54 字数 400 浏览 4 评论 0原文

我有一个对象的方法,它创建对象,然后将其传递给另一个线程中另一个对象的方法,如下所示:

MyClass* myClass = [[MyClass alloc] init];
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];

在方法中,我立即保留该对象,假设它会被创建者以某种方式释放。我的问题是:如何让 MyClass 正确释放该对象?这是正确的方法吗?

我的解决方案是在方法中手动释放对象。无论如何,我发现泄漏分析器仍然将其识别为泄漏,并且似乎这不是苹果所建议的,因为所有者有责任释放该对象。

你能解释一下处理这种情况的正确方法吗?谢谢!

I have a method of an object which creates objects which are then passed to a method of another object in another thread, like this:

MyClass* myClass = [[MyClass alloc] init];
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];

in method, I immediately retain the object, supposing it will be somehow released by the creator. My question is: how do I make MyClass release that object correctly? Is this the correct way to go?

My solution was to release the object manually in method. I see anyway that the Leak analyzer still recognizes this as a leak and seems it is not what Apple recommends, as the owner has the responsability to release the object.

Can you explain me the correct way to handle this situation? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅笑依然 2024-10-18 03:54:54

我不完全理解您想要实现的目标,但总的来说:

您不应该担心谁以及何时释放/解除分配对象。相反,只要确保在(您的单个对象或方法)开始需要它时保留它,并在不再需要它时释放它(或自动释放它,在在这种情况下,它将在您调用 autorelease 的线程上释放)。

这正是performSelectorOnMainThread:withObject:waitUntilDone: 的工作方式。来自文档

此方法保留接收者和 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 会“直到执行后”(该方法返回)。
  • 如果以后需要它,则应将其分配给保留它的属性。

I don't fully understand what you're trying to achieve, but in general:

You shouldn't worry about who and when releases/deallocates the object. Instead, just make sure to retain it when you (a single object or method of yours) start needing it and release it when you stop needing it (or autorelease it, in which case it will be released on the thread on which you called autorelease).

This is exactly the way the performSelectorOnMainThread:withObject:waitUntilDone: works. From the documentation:

This method retains the receiver and the arg parameter until after the selector is performed.

It retains them while it needs them for doing it's job.

In short, the mehod that creates the objects and sends them to another thread should be:

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.

or

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];

The way you have it now is a memory leak.

The receiving method:

  • if it uses the object only internally, doesn't have to retain it, since performSelector does "until after it is performed" (the method returns).
  • if it needs it later, it should be assigned to a property which retains it.
残龙傲雪 2024-10-18 03:54:54

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

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

方法中释放myClassanotherClass或两者都完全可以。

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

Your question is very hard to understand because you talk about this object, that object, another object and use meaningless names like myClass, anotherClass and method. It remains unclear which object you intend to release and which one is reported as leaking.

Anyhow, multi-threading doesn't add any special complexity to reference counting. Certainly, your two object myClass and anotherClass aren't short-lived objects. So if you use autorelease, make sure that the reference counter doesn't go to 0 if all autoreleases have been executed.

It's perfectly okay to release either myClass or anotherClass or both in method.

You don't show a lot of code. But what you show is okay.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文