使用除主线程之外的应用程序生命周期线程

时间:2011-08-13 10:39:32

标签: iphone objective-c multithreading nsthread nsoperation

我有一个多线程应用程序,其中每个线程都需要做一些工作,但在某一点上某些代码需要串行执行(比如写入sqlite3数据库),所以我调用的代码是使用以下命令在主线程上执行:

[self performSelectorOnMainThread:@selector(serialJob:) withObject:object waitUntilDone:YES];

并且每件事都很顺利,除非当代码需要一些时间时,用户与应用程序的交互被禁用直到该代码完成,所以有没有办法制作另一个可以在后台运行的ONE线程只要我需要它就像主要的那样被调用,所以我可以用以下代码替换之前的调用:

[self performSelector:@selector(serialJob:) onThread:REQUIRED_THREAD withObject:object waitUntilDone:YES];

这个线程应该是一些类的静态数据成员,可以从整个代码中访问。

任何帮助都会非常感激,并提前多多感谢...

3 个答案:

答案 0 :(得分:2)

这很容易做到,只是生成你的线程并让它使用[[NSRunLoop currentRunLoop] run]运行它的runloop。这就是将performSelector:onThread:与自定义线程一起使用所需的全部内容。

如果您使用的是iOS 4或更高版本,则应考虑使用Grand Central Dispatch队列而不是线程。 GCD API更易于使用,可以更好地利用系统资源。

答案 1 :(得分:1)

如同斯文所提到的那样,请查看Grand Central Dispatch

您可以像这样创建一个队列:

dispatch_queue_t myQueue = dispatch_queue_create("com.yourcompany.myDataQueue", NULL);

现在您可以在该队列上调用块:

dispatch_async(myQueue, ^{
  // Your code to write to DB.
});

完成后,不要忘记释放队列:

dispatch_release(myQueue);

答案 2 :(得分:0)

由于我的问题,我需要阻止当前线程,直到数据库作业完成,我已经尝试了这两个解决方案,他们工作得很好。您可以使用关键部分或NSOperationQueue,我更喜欢第一个,这里是两个代码:

定义一些类“DatabaseController”并将此代码添加到其实现中:

static NSString * DatabaseLock = nil;
+ (void)initialize {
    [super initialize];
    DatabaseLock = [[NSString alloc] initWithString:@"Database-Lock"];
}
+ (NSString *)databaseLock {
    return DatabaseLock;
}

- (void)writeToDatabase1 {
    @synchronized ([DatabaseController databaseLock]) {
        // Code that writes to an sqlite3 database goes here...
    }
}
- (void)writeToDatabase2 {
    @synchronized ([DatabaseController databaseLock]) {
        // Code that writes to an sqlite3 database goes here...
    }
}

要使用NSOperationQueue,您可以使用:

static NSOperationQueue * DatabaseQueue = nil;
+ (void)initialize {
    [super initialize];

    DatabaseQueue = [[NSOperationQueue alloc] init];
    [DatabaseQueue setMaxConcurrentOperationCount:1];
}
+ (NSOperationQueue *)databaseQueue {
    return DatabaseQueue;
}

- (void)writeToDatabase {
    NSInvocationOperation * operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(FUNCTION_THAT_WRITES_TO_DATABASE) object:nil];
    [operation setQueuePriority:NSOperationQueuePriorityHigh];
    [[DatabaseController databaseQueue] addOperations:[NSArray arrayWithObject:operation] waitUntilFinished:YES];
    [operation release];
}

这两个解决方案会阻塞当前线程,直到完成对数据库的写入,在大多数情况下您可以考虑这些。