xcode - 如何 CFRelease 必须返回的 CGEventRef?

标签 xcode macos automatic-ref-counting macos-carbon core-foundation

我以两种方式拦截 CGEventRef:

  • 返回值 NULL 以终止事件
  • 通过 CGEventCreateKeyboardEvent() 为事件分配一个新的 CGEventRef

Xcode 的分析器告诉我在创建新事件时存在潜在泄漏。但是我需要返回那个新事件,所以我不能在那里CFRelease

  • 这个 Xcode 错误是否有效?

  • 我应该在哪里正确CFRelease我创建的新 CGEventRef?

  • 无论是空事件还是新事件,我都不知道是否需要释放事件之前的值。

  • 在方法名称后附加“new”是否是解决此问题的正确方法?我认为可能是这样,例如我创建一个新事件时的情况。但是其他情况呢?

.

- (CGEventRef)modifySomeKeyboardEvents:(CGEventRef)event {

    CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
    NSLog(@"keycode: %d", keycode);

    switch (keycode) {
        case 0:
            NSLog(@"pressed 'a'");
            //Kill the event
            event = NULL;

            //Is a `CFRelease` of some kind needed here, to release the previous value?

            break;

        case 38:
            NSLog(@"pressed 'h'");

            //Send different character:
            CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
            CGEventRef newKeyEvent = CGEventCreateKeyboardEvent(eventSource, 1, true);
            CGEventSetIntegerValueField(newKeyEvent, kCGKeyboardEventKeycode, 51); // keycode '51' = backspace
            CFRelease(eventSource);

            event = newKeyEvent;

            //Can't CFRelease here, but somewhere?
            //CFRelease(newKeyEvent);

            break;

        default:
            break;
    }

    //Xcode error: "Potential leak of an object stored in newKeyEvent"
    return event;
}

最佳答案

The CGEventTapCallback documentation

After the new event has been passed back to the event system, the new event will be released along with the original event.

因此,您负责发布新事件或旧事件。

分析器不知道这一点,所以你需要告诉它。您可以通过将 new 放在方法名称的 beginning 来使分析器静音,但使用 copy 可能会更清楚,这也会使分析器静音警告:

- (CGEventRef)copyOrModifyKeyboardEvent:(CGEventRef)event {

(我想 newOrModifiedKeyboardEvent: 也可以。)

我相信分析器也应该对此进行标记,因为它现在在您仅返回输入事件时无法返回 +1 引用计数。但在我的测试中,它没有。 Xcode 4.6.2 分析器没有给我这个方法的警告:

- (CGEventRef)copyOrModifyEvent:(CGEventRef)event {
    CGEventRef newEvent;
    if (CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode) == 38) {
        newEvent = CGEventCreate(NULL);
    } else {
        newEvent = event;
    }
    return newEvent;
}

关于xcode - 如何 CFRelease 必须返回的 CGEventRef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16094398/

相关文章:

iPhone 无法使用 type= @"mp3"播放 mp3 声音

iphone - 如何在2部分中激活tableView didSelectRowAtIndexPath?

ios - XCode 8.1 更改了 Storyboard View 中的常量

macos - 操作系统: get size on disk for a file/directory

iphone - ARC 循环保留检测

iOS:指向数组的指针引用

ios - 如何将源代码从 xcode 转移到另一个开发人员?

ios - 如何从我的 Mac 应用程序重新启动 iOS 设备并恢复出厂设置

linux - 如何在 Mac 上创建目录的 Linux 兼容 zip 存档

ios - 使用 ARC 的线程安全设计