我有一个应用程序,在那里我使用函数FSMoveObjectToTrashSync。它在后台线程中工作。我需要能力为我的应用程序,点击按钮暂停或继续(如果它暂停)我怎么能使它?代码示例:
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:抱歉我的英语不好,我来自白俄罗斯…= ( 一个解决方案是将单个线程上的for
循环替换为NSOperation子类。每个操作应该只丢弃一个对象;然后为每个想要丢弃的对象创建一个操作,并将所有操作放在NSOperationQueue上。
操作队列将在一个线程上运行每个操作,如果有足够的计算能力,它甚至可以在多个线程上运行多个操作。
操作队列可以随意暂停和恢复;当您挂起队列时,该队列中已经在运行的任何操作都将完成,但是在您恢复队列之前不会启动其他操作。
你可以使用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被调用时,doback路基:将在一个后台线程上启动,但随后停止,因为没有任何工作要做。一旦notifyBackgroundThreadAboutNewWork被调用,dobackfoundation:将启动并处理新工作,然后返回睡眠状态,等待新工作可用,这将在下一次调用notifyBackgroundThreadAboutNewWork时发生。