主循环while循环未获取全局变量的当前值

时间:2014-04-30 19:45:51

标签: objective-c macos cocoa

我有一个 Xcode 5 / Cocoa程序,在指定的时间间隔内点击鼠标左键指定的次数。那部分工作正常。当我想过早地停止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));
    }
}

2 个答案:

答案 0 :(得分:0)

Cocoa / Cocoa Touch应用程序是一个基于事件的环境,所以你不能长时间运行&#34;循环&#34;在主线程中,当您停止处理和交付事件时。

当您的循环结束时,UI可以更新您看到的位,因为它现在可以传递事件。

您需要在后台线程或其他类似的工作中完成此项工作。

答案 1 :(得分:0)

好的,这是有效的 - 对主循环使用dispatch_async(全局类型),对更新标题的代码使用dispatch_async(主队列)。