主线程

时间:2017-07-04 22:36:54

标签: ios objective-c memory rendering uigraphicscontext

我正在使用在主线程上执行的关注代码来截取关闭屏幕(不是self.view的子视图)视图的屏幕截图,然后显示在{{1 }}。一切都在功能方面运行良好,但是因为这个代码是在扩展上运行的,所以存在更严格的内存界限(我读过~30 MB是上限?),

UIImageView

只要按下UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.screenshotView.frame.size.width, self.screenshotView.frame.size.height-2), YES, 0.0f); CGContextRef context = UIGraphicsGetCurrentContext(); [self.screenshotView.layer renderInContext:context]; _generatedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); self.previewImageView.image = _generatedImage; ,就会使用performSelectorOnMainThread调用此代码所在的方法。还会出现一个UIButton来处理UI的冻结,但是如果连续按下按钮(在解除UIAlertController之后),前几次内存使用将保持在基线附近(〜 15 MB),然后加标到~30 MB并保持在那里,直到几秒后再次调用该方法,然后当它完成渲染时,它会回落到~15 MB。

我不确定导致这种行为的原因是什么,为什么内存使用量不会一直保持在15 MB左右,而且我不确定当连续调用该方法时它会出现什么样的情况。听起来更像是有时会发生一件事吗?我怎样才能确保不会发生这种情况,只有在可以安全再次渲染而不增加内存使用时才会忽略UIAlertController

2 个答案:

答案 0 :(得分:3)

内存峰值不是由renderInContext:调用引起的,尽管所有内容都包括指向它的工具,但这是由于捕获的subviews的{​​{1}}引起的。在我的情况下,这是一个错误的约束导致UIView将其UITextView设置为height

对于有这样的问题并且无法解决问题的人,请从2000继续前进并查看您的子视图以确保它们正确无误。

答案 1 :(得分:1)

1.您能详细说明为什么要在主线程上捕获屏幕截图?使用以下命令运行async:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
});

这可能会解决挂起问题&尝试在autoreleasepool中执行这些代码行,这将有助于减少内存占用量。

2.你试过drawViewHierarchyInRect: afterScreenUpdates:它的速度要快得多吗?可以提高效率并帮助解决你的记忆问题。

该方法呈现到上下文然后您可以调用:

CGImageRef image = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());

但它应该在autoreleasepool内执行。如果没有,则记忆继续上升。

修改

3.如果你可以通过同步捕获方法来防止多个上下文创建。它可能有助于增加内存:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_queue_t renderQueue = dispatch_queue_create("com.throttling.queue", NULL);

- (void) captureScreen {
    if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW) == 0) {
        dispatch_async(renderQueue, ^{
            // capture
            dispatch_semaphore_signal(semaphore);
        });
    }
}