在 macOS Objective-C 应用程序中,我需要以编程方式重新启动应用程序这有效,但重新启动的应用程序有 1Gb 的内存泄漏有什么线索吗?

问题描述

我正在编写一个 macOS Objective-C 应用程序,它在启动时有一个登录屏幕。在设置中,有相应的“注销”功能在这种情况下,我决定强制重新启动应用程序,这样我就不必涵盖新情况,并使我更加确定注销不会产生不需要的副作用。所以我实施了我在网上找到的解决方案之一,具体如下:

- (void)automaticallyRestartApp:(id)sender {
    relaunch([[NSBundle mainBundle] bundleURL].path);
    dispatch_async( dispatch_get_main_queue(),^{
        [NSApp terminate:self];
    });
}

使用重新启动功能

static void relaunch(Nsstring *destinationPath) {
// The shell script waits until the original app process terminates.
// This is done so that the relaunched app opens as the front-most app.
int pid = [[nsprocessInfo processInfo] processIdentifier];

// Command run just before running open /final/path
Nsstring *preOpenCmd = @"";
Nsstring *deletePrefsCmd = @"rm";

Nsstring *wevpnPreferencesPath = [[[[[[nsprocessInfo processInfo] environment] objectForKey:@"HOME"] stringByAppendingPathComponent:@"Library"] stringByAppendingPathComponent:@"Preferences"] stringByAppendingPathComponent:@"com.vpn.osx.alfonso.plist"];

Nsstring *quotedDestinationPath = ShellQuotedString(destinationPath);

// OS X >=10.5:
// Before we launch the new app,clear xattr:com.apple.quarantine to avoid
// duplicate "scary file from the internet" dialog.
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
    // Add the -r flag on 10.6
    preOpenCmd = [Nsstring stringWithFormat:@"/usr/bin/xattr -d -r com.apple.quarantine %@",quotedDestinationPath];
}
else {
    preOpenCmd = [Nsstring stringWithFormat:@"/usr/bin/xattr -d com.apple.quarantine %@",quotedDestinationPath];
}

Nsstring *script = [Nsstring stringWithFormat:@"(while /bin/kill -0 %d >&/dev/null; do /bin/sleep 0.1; done; %@ %@; %@; /usr/bin/open %@) &",pid,deletePrefsCmd,ShellQuotedString(preferencesPath),preOpenCmd,quotedDestinationPath];

[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c",script,nil]];
}

直到最近我一直对这个实现感到高兴,因为我发现我的应用程序在重新启动时具有非常高的内存使用率,特别是当用户在输入其凭据后单击登录时。内存占用保持 1500Mb 大约 3 秒,然后,当用户登录时,它恢复正常。首次启动应用程序时,当用户执行相同操作时,内存占用并没有增加。首先,我认为这是由于重新启动功能非常脏造成的,从某种意义上说。所以我查看了网络,我发现了这个 page,其中使用辅助守护程序实现了相同的重新启动行为。我认为这看起来肯定更优雅并且可以解决问题,但不幸的是发生了完全相同的情况。登录自动重新启动时占用大量内存。 我的应用程序已经使用了一个守护进程,所以我在与守护进程的 xpc 通信中添加一个方法。这是我在xpc协议中的相关方法的实现:

- (void)askServicetorelaunchHostAppAtPath:(Nsstring *)hostAppPath withReply:(void     (^)(BOOL))reply {

    self.relaunchHostAppExecutablePath = hostAppPath;

    self.shouldrelaunchHostAppOnNextHostAppQuit = YES;

    reply(YES);
}

然后,在宿主应用程序退出调用的守护进程的方法中,有:

if (self.shouldrelaunchHostAppOnNextHostAppQuit) {
    self.shouldrelaunchHostAppOnNextHostAppQuit = NO;
    
    dispatch_after(dispatch_time(disPATCH_TIME_Now,(int64_t)(25 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
        NSError *error;

       NSRunningApplication __unused *relaunchedHostApp = [[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:self.relaunchHostAppExecutablePath] options:0 configuration:@{} error:&error];
        
        self.relaunchHostAppExecutablePath = nil;
    });
    
}

如前所述,这种完全不同的方法会得到完全相同的坏内存结果。您将读入我试图让守护程序在重新启动应用程序之前等待 25 秒的守护程序代码。不幸的是,这也没有帮助。非常感谢任何可能的建议。感谢您的关注。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...