【问题标题】:Is it safe to alloc a NSThread and then initWithTarget the thread multiple times?分配一个 NSThread 然后多次 initWithTarget 线程是否安全?
【发布时间】:2011-11-17 03:48:55
【问题描述】:

我有一个 Quartz Composer 的自定义补丁,它是一个多播接收器。它为守护进程启动一个 NSThread,然后在用户更改多播地址或端口号时重新启动它。

当补丁启动时,我会执行以下操作来启动一个新线程。

daemonThread = [NSThread alloc];

然后,每次我启动或重新启动线程时,我都会重新初始化它:

[daemonThread initWithTarget:multicastDaemon selector:@selector(doWorkWithDelegate:) object:self];
[daemonThread start];

当然,我每次在重新启动线程之前都会终止它。我没有使用垃圾收集,当补丁退出时我确实释放了 daemonThread。

我担心的是,当我像这样一遍又一遍地重新初始化这个线程时,我不确定会发生什么。我注意到 Instruments 告诉我我正在泄漏一个 NSThread 和一个 autoreleasepool,我怀疑这可能是我来自守护线程的池。我可以看到每次我重新启动该过程时这些数字都会增加,但我对 Instruments 不够熟悉,不知道它告诉我什么。

我应该担心吗?

【问题讨论】:

    标签: objective-c memory-leaks nsthread nsautoreleasepool


    【解决方案1】:

    在任何已经初始化的对象上调用任何init... 方法都是不安全的。这包括 NSThread。

    【讨论】:

    • 如果线程退出了怎么办?我这样做是为了让线程有一个带有 didFinish 类型方法的委托,该方法在 usleep 然后退出之前被调用。该方法通过 ivar 设置一个标志,表示线程已死。然后,下一帧看到该帧已死,并像您在上面看到的那样初始化一个 daemonThread。那安全吗?我知道 NSThread 无法重新启动,这就是我最终这样做的原因。如果不安全,还有什么安全的替代方案?
    • @Adam 在单个对象上多次调用初始化程序是不安全的。期间。
    • 安全的替代方法是分配一个新的 NSThread。你不知道 NSThread 可能在幕后分配了哪些资源,它只在dealloc 中发布,因此如果你初始化它两次就会泄漏。如果你正在使用它,你也可能会搞砸 ARC。 "It is undefined behavior for a program to cause two or more calls to init methods on the same object, except that each init method invocation may perform at most one delegate init call."
    • 感谢您的帮助!我已经把 daemonThread 从一个 ivar 变成了一个局部变量。我创建了一个新的局部变量来指向 daemonThread,这样我仍然可以引用他来释放他。这摆脱了 NSThread 泄漏。然后,我仍然有 nsautoreleasepool 泄漏。我注意到我在 daemonThread 中的 [NSThread exit] 在我的自动释放池中,所以我将它移到池外。做到了。没有更多的泄漏!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    相关资源
    最近更新 更多