连续调用[NSPasteboard canReadObjectForClasses:options:]会导致内存膨胀

时间:2018-09-12 18:27:38

标签: objective-c appkit nspasteboard

我正在使用以下简单的Objective-C程序,使用NSPasteboard作为两个进程之间的通信方式,从另一个进程接收消息并显示警报。该程序对我有用,但是我发现该程序正在消耗大量RAM,无论伙伴进程是否正在将新消息发布到粘贴板和是否进入内部警报块。在运行之前,它每隔几分钟就会在/private/var/vm/中产生1G交换文件,直到我杀死它。

我通过Xcode Instruments运行了该程序,并且看到[NSPasteboard canReadObjectForClasses:options:]每次都在创建持久性__NSArrayI对象,这是RAM膨胀的原因。有人可以确认吗?这是[NSPasteboard canReadObjectForClasses:options:]中的错误,还是我应该以不同的方式执行此任务?

编辑:
我最初忘记启用ARC。但是,即使启用了ARC,内存使用量的增长仍然大大超过了自动内存释放,并且随着时间的推移,交换文件仍在创建中。是否有人建议我如何重写此脚本以使用比while(true)更好的约定,以使[NSPasteboard canReadObjectForClasses:options:]的调用减少?我仍然感到奇怪的是,这个AppKit函数没有自动释放它创建的__NSArrayI对象,并假定ARC将负责处理它。这样的图书馆有这种惯例吗?

#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <AppKit/Appkit.h>

int main(void) {
    NSPasteboard *pb = [NSPasteboard pasteboardWithName:@"alertBoard"];
    NSArray *clsss = @[[NSString class]];
    while(true) {
        if ([pb canReadObjectForClasses:clsss options:nil]) {
            NSArray *contents = [pb readObjectsForClasses:@[[NSString class]] options: nil];
            CFStringRef msg  = (__bridge CFStringRef) [contents firstObject];
            [pb clearContents];

            CFUserNotificationDisplayNotice(2, 3, NULL, NULL, NULL, CFSTR("Alert"), msg, NULL);
        }   
    }   
    return 0;
}

我正在像g++ -framework Foundation -framework CoreFoundation -framework AppKit -fobjc-arc alertDaemon.m -o alertDaemon那样编译程序。不管其他进程如何,都会发生此问题,因此只需运行几分钟即可观察交换文件的创建。

1 个答案:

答案 0 :(得分:0)

我想出了一个使用lhs shape= [105,400] rhs shape= [111,400] 来检查粘贴板而不是[NSPasteboard changeCount]的解决方案。现在,程序使用一致的少量内存,而不用消耗RAM。现在,我只需要弄清楚如何使用较少的CPU周期,尽管比使用连续轮询检查NSPasteboard are scare更好的解决方案。

[NSPasteboard canReadObjectForClasses:options:]