Objective c objc泄漏行为我可以';无法解释
下面的代码循环不会泄漏内存(通过观察它在“top”下无限循环来验证) 我也没想到会这样。但是,当我复制指向位图数据的指针时,如下所示:Objective c objc泄漏行为我可以';无法解释,objective-c,cocoa,macos,Objective C,Cocoa,Macos,下面的代码循环不会泄漏内存(通过观察它在“top”下无限循环来验证) 我也没想到会这样。但是,当我复制指向位图数据的指针时,如下所示: NSBitmapImageRep *this_bmap = 0; while (1) { CGImageRef windowImage = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow,
NSBitmapImageRep *this_bmap = 0;
while (1) {
CGImageRef windowImage =
CGWindowListCreateImage(CGRectNull,
kCGWindowListOptionIncludingWindow,
windowID, kCGWindowImageDefault);
this_bmap = [[NSBitmapImageRep alloc] initWithCGImage:windowImage];
void *pixels1 = [this_bmap bitmapData];
[this_bmap release];
CGImageRelease(windowImage);
}
这件事现在泄漏得很厉害。我可以看到这种情况在“顶部”下迅速发生,程序最终停止运行
我不熟悉Objective-C,但我对编程并不陌生,我无法理解这种行为。bitmapData方法的文档声称它只返回一个指针(而不是分配一些东西),所以我被难住了。不久前我发现了一个类似的问题,但唯一的答案是“查看池”,我不认为这有什么帮助
知道这里发生了什么吗?嗯,我不是大师,所以我只是在猜测。但我突然意识到,每次循环都是在有效地声明一个名为pixels1的新变量。因此,每次通过您分配一些新的空间,而不是重复使用它。尝试将像素1的声明移动到循环之外,看看会发生什么 注意,这只是一个猜测,可能是错误的。一个更有知识的人可能会给你一个明确的答案。调用“initWithCGImage:”的文档中有以下内容: 讨论 如果你使用这种方法,你会 应处理生成的位图 NSBitmapImageRep对象为只读。 因为它只保留中的值 cgImage参数,而不是 解包数据,访问 像素数据需要创建一个 该数据在内存中的副本。变化 这样,数据就不会保存回 核心图形图像
这似乎表明需要释放bitmapData返回的内存。访问像素数据会导致对象被保留并自动删除,这样位图数据不会突然消失。要查看您的预期结果(即每次迭代循环不消耗内存),请重写为: NSBitmapImageRep*此_bmap=0
while (1) {
NSAutoreleasePool* loopPool = [NSAutoreleasePool new];
CGImageRef windowImage =
CGWindowListCreateImage(CGRectNull,
kCGWindowListOptionIncludingWindow,
windowID, kCGWindowImageDefault);
this_bmap = [[NSBitmapImageRep alloc] initWithCGImage:windowImage];
void *pixels1 = [this_bmap bitmapData];
[this_bmap release];
CGImageRelease(windowImage);
[loopPool drain];
}
这起作用了。我不明白,所以我有一些家庭作业要做。非常感谢。没有太多作业要做。自动释放的对象放入池中,待池排空/释放时释放。这发生在运行循环中处理的每个事件结束时(即,在接收到事件后完成所有调用堆栈)。如果您有这样一个紧密的循环,那么池将很快被填满,直到整个循环(以及随后的所有调用)完成后才会被排空。为循环的每次迭代创建并排空一个新的自动释放池意味着池永远不会变大。不会,因为从
bitmapData
返回的指针不是指向CF对象的。试图CFRelease
将导致崩溃。
while (1) {
NSAutoreleasePool* loopPool = [NSAutoreleasePool new];
CGImageRef windowImage =
CGWindowListCreateImage(CGRectNull,
kCGWindowListOptionIncludingWindow,
windowID, kCGWindowImageDefault);
this_bmap = [[NSBitmapImageRep alloc] initWithCGImage:windowImage];
void *pixels1 = [this_bmap bitmapData];
[this_bmap release];
CGImageRelease(windowImage);
[loopPool drain];
}