2011-12-15 99 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時發生。