2014-04-30 81 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(主队列)。