2014-04-30 110 views
0

我有一個Xcode 5 /可可程序,指定的時間間隔後點擊鼠標左鍵指定的次數。這部分工作正常。當我想要提前停止while循環時會出現問題。主while循環沒有得到全局變量的當前值

我正在使用監聽程序在程序運行期間檢測到任何按鍵,設置一個stopnow變量並檢查while loop中的變量。但是,在循環結束之前,while loop不檢測變量中的更改。

此外,我在窗口的標題欄中更改計數器以顯示已完成的點擊次數,並且在循環結束前不會更新。

當我按下某個鍵時,確實收到了NSLog消息。

我很困惑。

我的代碼是在這裏:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    // Insert code here to initialize your application 

[[self myWindow] setLevel:NSFloatingWindowLevel]; 

[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event) { 
    keychar = (unichar) event.characters; 
    [NSApp activateIgnoringOtherApps:YES]; 
    stopnow = 1; 
    NSLog(@"Key Pressed = x%x (%x) (%x)",keychar,(keychar&0x7f00),((keychar&0xff00)>>8)); 
}]; 
} 
- (IBAction)setClickPoint:(NSButton *)sender { 
    sleep(5); 
    CGEventRef ourEvent = CGEventCreate(NULL); 
    cgPoint = CGEventGetLocation(ourEvent); 

    myPoint = [NSString stringWithFormat:@" (%5.0f,%5.0f)", cgPoint.x, cgPoint.y]; 
    myNewTitle = [mytitle stringByAppendingString:myPoint]; 
    [[self myWindow] setTitle:myNewTitle]; 
    } 

(IBAction)strtButton:(NSButton *)sender { 
    NSLog(@"Entered strButtn"); 
    numClicks = [_nClicks intValue]; 
    numWait = [_nWait floatValue]; 
    i = 0; 
    while (i < numClicks || numClicks == 0) { 
     i++; 
     myTotal = [NSString stringWithFormat:@" %i of %i", i, numClicks]; 
     myNewTitle = [mytitle stringByAppendingString:myPoint]; 
     myNewTitle = [myNewTitle stringByAppendingString:myTotal]; 

     [[self myWindow] setTitle:myNewTitle]; 

     CGWarpMouseCursorPosition(cgPoint); 

     CGEventRef down = CGEventCreateMouseEvent(0, kCGEventLeftMouseDown,cgPoint, 0); 
     CGEventPost(kCGSessionEventTap, down); 
     CFRelease(down); 

     CGEventRef up = CGEventCreateMouseEvent(0, kCGEventLeftMouseUp,cgPoint, 0); 
     CGEventPost(kCGSessionEventTap, up); 
     CGRealease(up); 

     NSLog(@"stopnow = %i", stopnow); 

     if (stopnow == 1) { 
      stopnow = 0; 
      break; 
     } 

     usleep((unsigned int)(numWait * 1000000.0)); 
    } 
} 

回答

0

可可/可可觸摸應用程序是一個基於事件的環境,所以你不能有長時間運行的「循環」中的主線程,當你停止處理並交付活動。

當循環結束時,用戶界面能夠更新您所看到的位,因爲它現在可以傳遞事件。

您將需要在後臺線程或其他一些工作中完成這項工作。

+0

那個低調的匿名懦夫會喜歡解釋爲什麼嗎? – Droppy

+0

所以 - 你是說我需要使循環另一種方法,並創建一個線程與該方法?如果是這樣,新線程將如何通知主線程它已完成?也許一個回調方法? – user3581648

+0

是的,任何UI更新都可以通過GCD完成,調度到主隊列。 – Droppy

0

好的,這裏有什麼作用 - 對主循環使用dispatch_async(全局類型),對更新標題的代碼使用dispatch_async(主隊列)。