NSStatusBar 菜单栏图标 NSMenu 泄漏 CFData

NSStatusBar menu bar icon NSMenu leaking CFData

我有一个奇怪的数据泄漏,希望有人能解释这里出了什么问题。最小工作示例项目如下:

  1. 创建一个新的 Objective-C macOS 项目(Cocoa-App)。
  2. 删除除 Info.plistmain.m
  3. 之外的所有内容
  4. Info.plist 中执行:
    • 删除条目 Main nib file base name
    • Principal class 更改为 "AppHook"。
    • 添加 LSUIElement 并将其设置为 YES

接下来,将 main.m 更改为:

#import <Cocoa/Cocoa.h>
#import "AppHook.h"

int main(int argc, const char * argv[]) {
    [[AppHook sharedApplication] run];
    return 0;
}

并添加这两个新文件:AppHook.h

#import <Cocoa/Coco a.h>

@interface AppHook : NSApplication <NSApplicationDelegate, NSMenuDelegate>
@property (strong) NSStatusItem *barItem;
@end

AppHook.m:

#import "AppHook.h"

@implementation AppHook
- (instancetype)init {
    self = [super init];
    self.delegate = self;
    return self;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.barItem = [NSStatusBar.systemStatusBar statusItemWithLength:NSVariableStatusItemLength];
    self.barItem.highlightMode = YES;
    self.barItem.title = @"yep";
    self.barItem.menu = [[NSMenu alloc] initWithTitle:@"M"];
    self.barItem.menu.delegate = self;
    self.barItem.menu.autoenablesItems = NO;
}
- (NSInteger)numberOfItemsInMenu:(NSMenu*)menu {
    return 1;
}
- (BOOL)menu:(NSMenu*)menu updateItem:(NSMenuItem*)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel {
    item.title = [NSString stringWithFormat:@"%@", [NSDate date]];
    return YES;
}
@end

当 运行 使用 Instruments 和 Leaks 模板的应用程序时,我得到以下 CFData 泄漏:

0   Malloc      +1  1   00:03.319.300   AppKit  _DPSNextEvent
1   CFRetain    +1  2   00:03.319.303   AppKit  CopyCarbonUIElementAttributeValue
2   CFRelease   -1  1   00:03.319.310   AppKit  _DPSNextEvent

每次打开和关闭状态菜单时都会出现这种情况。所以反复点击菜单图标会造成一堆漏洞。

这里没什么特别的,只是 NSApplication 的子类(我需要重写 sendEvent(_:))。

所以...经过很长时间运行它又发生了。

简答:

重新启动您的 Mac。

长答案:

如您所见,我的最新评论是将近一个月前的事了。从那以后,我重新启动了我的 mac 两次,并且之前总是检查 Xcode Profiler。对于这两次重新启动,Profiler 没有显示任何泄漏。我不确定上次重启发生在大约两周前。今天我注意到 Profiler 再次显示相同的泄漏。

没有的是什么:

  • 正在清理缓存和 DerivedData 文件夹。
  • 退出 Xcode 并重新启动它。
  • 同时执行这两项操作以及这些操作的任何其他可能组合。

似乎是 macOS 本身的错误。我会创建错误报告,但老实说,我什至不知道该写什么。重现性只是偶然:-/
此外,它不依赖于特定项目。参考此样例工程,并在上个月未做任何改动。