2011-12-15 83 views
2

我有一个应用程序,我使用函数FSMoveObjectToTrashSync。它在后台线程中工作。我需要我的应用程序的能力,点击按钮暂停或继续(如果它暂停)我怎么能做到这一点?代码 例子:如何暂停/继续NSThread

NSMutableArray *fileArray = [NSMutableArray array withobjects:@"file1url", @"file2", @"file3", nil]; 
NSMutableArray *threadArray = [[NSMutableArray alloc] init]; 

-(void)myFunc{ 
    for (NSURL *url in fileArray){ 
     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(mySelectorWith:) object:url]; 
     [thread start]; 
     [threadArray addObject:thread]; 
    } 
} 

-(void)mySelectorWith:(NSURL *) url{ 
     FSRef source; 
     FSPathMakeRef((const UInt8 *)[[url path] fileSystemRepresentation], &source, NULL); 
     FSMoveObjectToTrashSync(&source, NULL, kFSFileOperationDefaultOptions); 
} 

PS:对不起我的英语,我来自白俄罗斯是... =(

回答

2

一种解决方案是用一个NSOperation子类替换单个线程上的for循环。每个操作应该只是垃圾一个对象;然后为每个想要垃圾的对象创建一个操作,并将所有操作放在NSOperationQueue上。

操作队列将在线程上运行每个操作,并且它甚至可以在多个线程上运行多个操作(如果它看到足够的计算能力来执行此操作)。

An operation queue can be paused and resumed at will;当您暂停队列时,该队列中已经运行的任何操作都将结束,但在恢复队列之前不会再有任何操作。

2

你可以使用一个NSConditionLock的NSConditionLock类似于条件变量它。一些基本的方法,lockWhenCondition和unlockWithCondition,以及lock。一个典型的用法是让你的后台线程用“lockWhenCondition:”等待条件锁,并且在你的前台线程中设置条件,这会导致后台线程醒来,条件是一个简单的整数,通常是一个枚举。

这里是一个例子:

enum { 
    kWorkTodo = 1, 
    kNoWorkTodo = 0 
} 

- (id)init { 
    if ((self = [super init])) { 
     theConditionLock = [[NSConditionLock alloc] initWithCondition: kNoWorkTodo]; 
     workItems = [[NSMutableArray alloc] init]; 
    } 
} 

- (void)startDoingWork { 
    [NSThread detachNewThreadSelector:@selector(doBackgroundWork) toTarget:self withObject:nil]; 
} 

- (void)doBackgroundWork:(id)arg { 
    while (YES) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     NSArray *items = nil; 
     [theConditionLock lockWhenCondition:kWorkTodo]; // Wait until there is work to do 
     items = [NSArray arrayWithArray:workItems] 
     [workItems removeAllObjects]; 
     [theConditionLock unlockWithCondition:kNoWorkTodo]; 
     for(id item in items) { 
      // Do some work on item. 
     } 
     [pool drain]; 
    } 
} 

- (void)notifyBackgroundThreadAboutNewWork { 
    [theConditionLock lock]; 
    [workItems addObject:/* some unit of work */]; 
    [theConditionLock unlockWithCondition:kWorkTodo]; 
} 

在这个例子中,当startDoingWork被称为doBackgroundWork:将开始在后台线程,但随后停止,因为没有任何工作要做。一旦notifyBackgroundThreadAboutNewWork被调用,那么doBackgroundWork:将启动并处理新的工作,然后返回休眠等待新工作可用,这将在下次调用notifyBackgroundThreadAboutNewWork时发生。