_UICreateScreenUIImage截图的内存管理

因为一些需求,程序里面会大量用到这个方法来截图 然后发觉当这个函数用的很多的时候会导致springboard重启,我想请教这个是不是内存泄漏的原因,如果是这个截图该怎么进行内存管理?

已解决,看上去似乎是要管理内存的原因,UIImage *screenImage= [_UICreateScreenUIImage() autorelease] 这样就好了 具体请大神解释 谢谢狗神

你看看syslog有没有respring信息,这个函数应该不存在内存泄露的问题

没有 但是崩溃日志会产生Unkonwn类型的,
Processes
Name rpages recent_max fds [reason] (state)
SpringBoard <5299e27756133806b7bc6e48e90c9f89> 56712 56712 200 [highwater]
其中SpringBoard的rpages是5万多,highwater,其他的只有几百
storebookkeeperd <1c81fce87e083e25ba7b704fad6496b9> 748 748 100 (daemon) (idle)
CloudKeychainPro <54cf19e7051635e2a4036ef7942e47f8> 132 132 100 (daemon) (idle)
aosnotifyd <81331f89aa773a79ac8ae5dfefc92c03> 334 334 50 (daemon) (idle)
softwarebehavior <2941f2acb0e4390c8b5cc7a852e7b040> 140 140 100 (daemon) (idle)
AppleIDAuthAgent <2c74cb66c08a366aafd64ac6395c2089> 145 145 50 (daemon) (idle)
afcd 120 120 200 (daemon) (idle)
keybagd 116 116 100 (daemon) (idle)
IMDPersistenceAg <8bf012da3a853ae794b97d0bcfc3119f> 212 212 100 (daemon) (idle)
xpcd <781ca484868033b69bdfec972d11e80e> 209 209 100 (daemon) (idle)

然后我尝试用autorelease
UIImage *screenImage= [_UICreateScreenUIImage() autorelease]
发现就解决了,再也没重启了。。。。这样看上去是不是就是要内存管理的原因?

官方文档的最下面说这样看来的话_UICreateScreenUIImage是不需要我们管理内存的。不过为了确认,你可以用IDA看看这个函数的内部实现,是不是返回了一个alloc过的UIImage

额 是个函数指针 这个该怎么调
Attributes: thunk

__UICreateScreenUIImage
LDR PC, =__imp___UICreateScreenUIImage
; End of function __UICreateScreenUIImage

你要分析UIKit这个库

频繁多次调用这个api是会有内存泄漏的,建议还是使用IOSurface等方式来进行

看到楼主的帖子,我也正好遇到这个问题,但是我使用楼主的方法,不行:
springboard 每间隔 1秒 去截图一次,然后存入相册。内存直线下滑,不知道是不是存入相册的问题,导致了无法释放呢?
while (isRunScreenshot) {
//UIImage *screenImage = _UICreateScreenUIImage();
UIImage *screenImage = [_UICreateScreenUIImage() autorelease];
UIImageWriteToSavedPhotosAlbum(screenImage, nil, nil, nil);
[NSThread sleepForTimeInterval:1];
NSLog(@"==================Running screenshot");
}
如有关注,非常感谢!

更新:我也使用了 __IOSurface 方法,但是存在同样的问题:内存一直向下掉
另外:我发现 加了 autorelease,只有:发个指令给 springboard 不要让它截图了,然后立刻内存全部释放了。
难道是在运行过程中,不能够释放?

2个建议:

  1. 不要用while和sleep的形式来做定时器,iOS原生提供了定时器NSTimer;
  2. 不要autorelease,直接release。
    代码改一下:
- (void)iOSRESaveScreenShot
{
    UIImage *screenImage = _UICreateScreenUIImage();
    UIImageWriteToSavedPhotosAlbum(screenImage, nil, nil, nil);
    [screenImage release];
}

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(iOSRESaveScreenShot) userInfo:nil repeats:YES];
[timer fire];

Hi, snakeninny,很感谢!
这两个建议,已经采纳,应用在springboard环节,效果不错。
现在内存很稳定,没有出现直线下滑的情况。下次我要多注意这个定时器的细节。
同时也感谢楼主 aspireios 的问答!

你好,请问是如何查看内存是否下滑呢?谢谢~