首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >iPhone:如何使用performSelector:onThread:withObject:waitUntilDone:方法?

iPhone:如何使用performSelector:onThread:withObject:waitUntilDone:方法?
EN

Stack Overflow用户
提问于 2010-04-06 19:26:01
回答 3查看 34.5K关注 0票数 18

我正在尝试使用一个单独的线程来处理一些API。

问题是我不能将performSelector:onThread:withObject:waitUntilDone:方法与我为此实例化的线程一起使用。

我的代码:

@interface MyObject : NSObject {
  NSThread *_myThread;
}
@property(nonatomic, retain) NSThread *myThread;
@end

@implementation MyObject
@synthesize myThread = _myThread;
- (NSThread *)myThread {
  if (_myThread == nil) {
    NSThread *myThreadTemp = [[NSThread alloc] init];
    [myThreadTemp start];
    self. myThread = myThreadTemp;
    [myThreadTemp release];
  }
  return _myThread;
}

- (id)init {
  if (self = [super init]) {
    [self performSelector:@selector(privateInit:) onThread:[self myThread] withObject:nil waitUntilDone:NO];
  }
  return self;
}
- (void)privateInit:(id)object {
  NSLog(@"MyObject - privateInit start");
}

- (void)dealloc {
  [_myThread release];
  _myThread = nil;
  [super dealloc];
}
@end

永远不会打印"MyObject - privateInit start"

我遗漏了什么?

我尝试使用目标和选择器实例化线程,尝试等待方法执行完成(waitUntilDone:YES)。

什么都没有用。

更新:

我不需要这个多线程来将代价高昂的操作分离到另一个线程。

在这种情况下,我可以使用几个答案中提到的performSelectorInBackground

使用这个单独线程的主要原因是需要从单个线程执行API中的所有操作(由Loquendo提供的TTS)。

这意味着我必须创建TTS对象的一个实例,并始终从同一线程调用该对象上的方法。

EN

回答 3

Stack Overflow用户

发布于 2010-07-13 17:46:59

这就是对我有效的方法。主循环取自苹果的文档http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW25

- (void) start {
    self.imageSaverThread = [[[NSThread alloc] initWithTarget:self selector:@selector(imageSaverThreadMain) object:nil] autorelease];
    [self.imageSaverThread start];
}

- (void) imageSaverKeepAlive {
    [self performSelector:@selector(imageSaverKeepAlive) withObject:nil afterDelay:60];    
}

- (void)imageSaverThreadMain
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Add selector to prevent CFRunLoopRunInMode from returning immediately
    [self performSelector:@selector(imageSaverKeepAlive) withObject:nil afterDelay:60];
    BOOL done = NO;

    do
    {
        NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
        // Start the run loop but return after each source is handled.
        SInt32    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);

        // If a source explicitly stopped the run loop, or if there are no
        // sources or timers, go ahead and exit.
        if ((result == kCFRunLoopRunStopped) || (result == kCFRunLoopRunFinished))
            done = YES;

        [tempPool release];
    }
    while (!done);

    [pool release];
}

希望能有所帮助

票数 13
EN

Stack Overflow用户

发布于 2010-05-08 05:38:42

好吧,我想我有一个更好的解决方案

- (void)run{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    running = true;
    [[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
    while (running && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]){
        //run loop spinned ones
    }

    [pool release];
}

我在这干嘛?

1)在此处添加模拟端口作为源将阻止runMode:beforeDate:方法立即退出。

2)在runLoop中有东西之前,方法runMode:beforeDate:会阻塞线程。

票数 4
EN

Stack Overflow用户

发布于 2010-04-06 19:36:12

您已经创建了线程,但它没有运行。它必须运行才能执行某些操作。

你也可以用"performSelectorInBackground“来代替。它将对调用进行排队,直到初始化完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2584394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档