委托来自其他NSThread的回调

时间:2011-08-09 09:19:35

标签: iphone objective-c xcode nsthread

我有.delegate属性的对象,我在方法'doJob'中操作。我将此属性赋值为'self',当此对象完成其作业时,我的函数被调用。直到现在一切都很好。

现在我想在一个单独的线程中操作这个对象。

我正在使用[NSThread detachNewThreadSelector ...]来运行'doJob'功能。 在这种情况下,我的委托方法没有被调用。我想这是因为'self'指向新线程而不是主线程。好。我在创建线程时将self作为函数的参数传递,但它仍然不起作用。我错过了什么?

我目前的代码如下:

- (void)mainFunction
{
    [NSThread detachNewThreadSelector:@selector(doJob:) toTarget:self witObject:self];
}

- (void)doJob:(MyObject*)parentThread
{
    ManipulatedObject *obj = [[ManipulatedObject alloc] init];
    obj.delegate = parentThread;
    [object startJob];
}

2 个答案:

答案 0 :(得分:1)

GCD会让您的大多数多线程问题变得微不足道。你可以这样做:

- (void)mainFunction
{
    // Runs your task on a background thread with default priority.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        ManipulatedObject * obj = [[ManipulatedObject alloc] init];

        [obj startJob];  // I'm assuming this is sychronous.

        // The callback is explicitly run on the main thread.
        dispatch_async(dispatch_get_main_queue(), ^{

            // Your callback here.

            [obj release];
        });
    });
}

这就是你所要做的一切,就这么简单。所有相关代码都是内联的和一起的。

如果您希望ManipulatedObject显式调用该块,则可以将该功能添加到ManipulatedObject。为此,你应该:

  1. 为便利typedef void(^MyCallback)();

  2. 定义块类型
  3. 添加@property (nonatomic, copy) MyCallback block;@synthesize block。不要忘记副本。

  4. 需要dispatch_async(dispatch_get_main_queue(), [self block]);时调用阻止。

  5. 如果您的委托需要进行多种回调,那么每次回调都需要一个块。这是一个小小的不便,但它为您获得的所有便利性是值得的。

    有关块和GCD的更全面解释,请查看WWDC 2011会话308。

答案 1 :(得分:0)

首先,你不需要传递self作为witObject:参数(拼写错误),因为 - (void)doJob:(MyObject *)parentThread仍然在同一个对象中(两个线程中的self相同) ),self与你的主线程无关,它的MyObject可能,你也有问题,如果你没有为你的doJob创建一个新的自动释放池:,doJob:应该看起来像

- (void)doJob:(MyObject*)parentThread
{
    NSAutoreleasePool    * pool = [[NSAutoreleasePool alloc] init];
    ManipulatedObject *obj = [[ManipulatedObject alloc] init];
    obj.delegate = parentThread;
    [object startJob];
    [pool release];
}

你必须向我们提供一些关于你如何调用委托方法的信息,如果它想要使用计时器或类似的东西,那么你将遇到问题,因为没有runloop来添加你的计时器。