gpt4 book ai didi

Objective-C block 未针对仅后台应用程序发布

转载 作者:搜寻专家 更新时间:2023-10-30 20:23:22 25 4
gpt4 key购买 nike

我有一个仅在后台运行的应用程序(通过在 info.plist 文件中指定 LSBackgroundOnly)。问题是,我在并行队列上运行的所有 block 都没有被释放。代码在内存管理的环境中执行 - 不涉及 GC。

(简化的)代码如下所示。 Blubber 只是一些虚拟类,它包含一个用于测试的 NSDate。此外,它会覆盖 retainreleasedealloc 以执行一些日志记录:

NSOperationQueue *concurrentQueue = [[NSOperationQueue alloc] init];
[concurrentQueue setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount];

Blubber *aBlubber = [[Blubber alloc] init];
aBlubber.aDate = [NSDate date];

[concurrentQueue addOperationWithBlock:^{
NSAutoreleasePool *blockPool = [[NSAutoreleasePool alloc] init];
NSDate *test = [aBlubber aDate];
NSLog(@"Block DONE");
[blockPool release];
}];

[aBlubber release];

[concurrentQueue release];

如果我将应用程序更改为普通(即非后台)应用程序,我可以观察到每当通过 UI 进行任何输入时释放的 block (即使将焦点更改到另一个窗口也足够)。由于我的后台应用程序直接通过 HID USB 驱动程序接收输入,并且它没有窗口或菜单栏,所以这不会发生。

有没有办法手动强制运行循环或任何负责告诉队列释放已完成 block 的方法?

(所有其他被 block 保留的对象也没有被释放,造成巨大的内存泄漏。这些泄漏不能被 Leaks 或 ObjectAllocations 工具发现,但使用 top 可以观察到内存消耗猛增。)

最佳答案

自动释放池的一个常见“陷阱”是,如果应用在未接收事件的情况下建立内存,最外层池(由事件循环管理的池)将不会耗尽。

我认为这不应该适用于此,因为您正在管理自己的池...但为了以防万一,您可以试试这个:

...
//When no events are coming in (i.e. the user is away from their computer), the runloop doesn't iterate, and we accumulate autoreleased objects
[[NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:@selector(kickRunLoop:) userInfo:nil repeats:YES] retain];
...
- (void) kickRunLoop:(NSTimer *)dummy
{
// Send a fake event to wake the loop up.
[NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined
location:NSMakePoint(0,0)
modifierFlags:0
timestamp:0
windowNumber:0
context:NULL
subtype:0
data1:0
data2:0]
atStart:NO];
}

关于Objective-C block 未针对仅后台应用程序发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3565600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com