我有.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];
}
答案 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
。为此,你应该:
为便利typedef void(^MyCallback)();
添加@property (nonatomic, copy) MyCallback block;
和@synthesize block
。不要忘记副本。
需要dispatch_async(dispatch_get_main_queue(), [self block]);
时调用阻止。
如果您的委托需要进行多种回调,那么每次回调都需要一个块。这是一个小小的不便,但它为您获得的所有便利性是值得的。
有关块和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来添加你的计时器。