2012-05-17 72 views
2

什麼等同於iOS中的Win32的WaitForMultipleObjects函數?在iOS中等待多個事件?

這大致就是我想:

NSCondition *condition1; 
NSCondition *condition2; 
NSCondition *condition3; 

wait_for_conditions([NSArray arrayWithObjects: condition1, condition2, condition3, nil], 
^{ 
    // Some code which must be executed when all conditions were fired 
}); 

// in some other places of program: 
[condition1 signal]; 

// ... 
[condition2 signal]; 

// ... 
[condition3 signal]; 

什麼是iOS中做到這一點的方法嗎?

編輯:我沒有綁定到NSCondition的使用,任何其他同步的東西都會好的(我剛剛搜索並找到NSCondition)。

回答

0

好的,我最終使用我自己的解決方案使用GCD的塊通知組。我還使用了串行隊列(而不是併發),它保證我們只創建1個附加線程。

@interface WaitCondition : NSObject 
    - (void) fire; 
@end 

@implementation WaitCondition { 
    BOOL fired; 
    NSCondition *condition; 
} 

- (id) init 
{ 
    if ((self = [super init])) { 
     condition = [NSCondition new]; 
    } 
    return self; 
} 

- (void) fire 
{ 
    [condition lock]; 
    [condition signal]; 
    fired = YES; 
    [condition unlock]; 
} 

- (void) wait 
{ 
    [condition lock]; 
    while (!fired) { 
     [condition wait]; 
    } 
    [condition unlock]; 
} 

@end 

void Dispatch_NotifyForConditions(NSArray *conditions, dispatch_block_t completion) 
{ 
    dispatch_queue_t queue = dispatch_queue_create("notify_queue", NULL); 
    dispatch_group_t group = dispatch_group_create(); 

    for (WaitCondition *condition in conditions) 
    { 
     NSCAssert([condition isKindOfClass:[WaitCondition class]], @"Dispatch_NotifyForConditions: conditions must contain WaitCondition objects only."); 
     dispatch_group_async(group, queue, ^{ 
      [condition wait]; 
     }); 
    } 

    dispatch_group_notify(group, queue, completion); 

    dispatch_release(queue); 
    dispatch_release(group); 
} 
+0

我很困惑,爲什麼需要觸發的變量?在大多數框架中,只需一個線程完成工作並調用信號,然後再調用另一個線程來等待,一旦調用信號,則任何服務器都會繼續執行...... – jjxtra

1

您可以使用唯一的通知名稱爲每個條件創建NSNotifications。 然後對於每個通知將調用相同的功能。

+0

我實際上需要最終的代碼來執行_once_。 – ivanzoid

+1

你可以很容易地讓被調用的函數只是一個檢查器,看看在調用你的主函數之前是否所有條件都滿足 – Dancreek

+0

@Dancreek'很容易'?我想不是。檢查我的答案'簡單'版本。哈。 –

1

這個怎麼樣?

void async(void (^block)()) 
{ 
    [NSThread detachNewThreadSelector:@selector(invoke) toTarget:[block copy] withObject:nil]; 
} 

__attribute__((sentinel(NULL))) 
void wait_for_conditions(void (^block)(), NSCondition *condition, ...) 
{ 
    va_list args; 
    va_start(args, condition); 

    NSMutableArray *conditions = [NSMutableArray array]; 

    do { 
     [conditions addObject:condition]; 
    } while ((condition = va_arg(args, NSCondition *))); 

    va_end(args); 

    NSCondition *overallCondition = [NSCondition new]; 

    for (int i = 0; i < conditions.count; i++) { 
     NSCondition *cond = [conditions objectAtIndex:i]; 

     async(^{ 
      [cond lock]; 
      [cond wait]; 
      [cond unlock]; 

      [overallCondition lock]; 
      [overallCondition signal]; 
      [overallCondition unlock]; 
     }); 
    } 

    for (int i = 0; i < conditions.count; i++) { 
     [overallCondition lock]; 
     [overallCondition wait]; 
     [overallCondition unlock]; 
    } 

    if (block) 
     block(); 
} 

很明顯,這有一個缺陷,有效地加倍你的線程,但我不知道是否有一個更簡單的方法來完成這一點。