NSStatusBar 菜单栏图标 NSMenu 泄漏 CFData
NSStatusBar menu bar icon NSMenu leaking CFData
我有一个奇怪的数据泄漏,希望有人能解释这里出了什么问题。最小工作示例项目如下:
- 创建一个新的 Objective-C macOS 项目(Cocoa-App)。
- 删除除
Info.plist
和 main.m
之外的所有内容
- 在
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 本身的错误。我会创建错误报告,但老实说,我什至不知道该写什么。重现性只是偶然:-/
此外,它不依赖于特定项目。参考此样例工程,并在上个月未做任何改动。
我有一个奇怪的数据泄漏,希望有人能解释这里出了什么问题。最小工作示例项目如下:
- 创建一个新的 Objective-C macOS 项目(Cocoa-App)。
- 删除除
Info.plist
和main.m
之外的所有内容
- 在
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 本身的错误。我会创建错误报告,但老实说,我什至不知道该写什么。重现性只是偶然:-/
此外,它不依赖于特定项目。参考此样例工程,并在上个月未做任何改动。