2011-08-13 35 views
2

我有一个多线程应用程序,其中每个线程都必须执行一些工作,但在某个点上需要连续执行一些代码(如写入sqlite3要使用在主线程上执行的数据库),所以我打电话的代码:使用除主线程以外的应用程序生命周期线程

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

和每一件事情去除了就好了,当代码需要一些时间,直到该代码与应用程序的用户交互被禁用已经完成了,那么是否有任何方法可以创建另一个可以在后台运行的ONE线程,并且可以在需要时随时调用,就像主线程一样,以便我可以用以下代码替换之前的调用:

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

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

任何帮助将是非常赞赏,并提前许多感谢...

回答

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... 
    } 
} 

OR使用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]; 
} 

这两种解决方案阻止当前线程,直到写入数据库完成后,你可以在大多数的情况下考虑。

2

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

如果你在iOS 4或更新的版本,你应该考虑使用Grand Central Dispatch队列,而不是线程。 GCD API更容易使用,并且可以更好地利用系统资源。

+0

请问您可以写一个关于如何创建该线程的示例代码(假设在applicationDelegate中),并将其初始化为在应用程序的生命周期中运行,而不管我在生命周期中创建了多少个操作。我的意思是应该在应用程序完成加载时创建该线程,并在关闭时删除该线程。 – Mousa

1

像Sven提到的,看看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); 
+0

感谢你的回答,但是这段代码是否使当前线程等待写入数据库的代码完成?正如我在使用waitUntilDone设置为YES来完成此问题中提到的那样。并再次感谢 – Mousa

相关问题