UIGraphicsGetCurrentContext() short lifetime

隐身守侯 提交于 2019-12-01 10:28:39

I found a useful thread on on the Apple Dev Forums describing this exact problem. It only exists since iOS 5.0 and the theory is that it is because Apple introduced a double buffering system, so the first two drawRects will always be full. However, there is no explanation for why this will happen again after idle. The theory is that the underlying buffer is not guaranteed by the GPU, and this will be discarded at whim and need to be recreated. The solution (until Apple issues some kind of real solution) is to ping the buffer so that it won't be released:

mDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(pingRect)];
[mDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

- (void)pingRect
{
    //Already drawing
    if(mTouchCount > 0) return;

    //Even touching just one pixel will keep the buffer alive
    [self setNeedsDisplayInRect:CGRectMake(0, 0, 1, 1)];
}

The only weakness is if the user keeps their finger perfectly still for more than 5 seconds, but I think that is an acceptable risk.

EDIT Interesting update. It turns out simply calling setNeedsDisplay is enough to keep the buffer alive, even if it returns immediately. So I added this to my drawRect method:

- (void)drawRect:(CGRect)rect
{
   if(rect.size.width == 1.f)
       return;
    //...
}

Hopefully, it will curb the power usage that this refresh method will surely increase.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!