我有一个多线程应用程序,其中每个线程都需要做一些工作,但在某一点上某些代码需要串行执行(比如写入sqlite3数据库),所以我调用的代码是使用以下命令在主线程上执行:
[self performSelectorOnMainThread:@selector(serialJob:) withObject:object waitUntilDone:YES];
并且每件事都很顺利,除非当代码需要一些时间时,用户与应用程序的交互被禁用直到该代码完成,所以有没有办法制作另一个可以在后台运行的ONE线程只要我需要它就像主要的那样被调用,所以我可以用以下代码替换之前的调用:
[self performSelector:@selector(serialJob:) onThread:REQUIRED_THREAD withObject:object waitUntilDone:YES];
这个线程应该是一些类的静态数据成员,可以从整个代码中访问。
任何帮助都会非常感激,并提前多多感谢...
答案 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];
}
这两个解决方案会阻塞当前线程,直到完成对数据库的写入,在大多数情况下您可以考虑这些。