我正在尝试从drawRect:
内的网址加载图片。我们的图像加载代码是一个如下所示的方法:- (void) loadImage:(NSURL*)url done:(void(^)(UIImage*))done;
,它创建一个异步NSURLConnection并回调图像。
所以,drawRect:
中的代码如下所示:
CGContextRef context = UIGraphicsGetCurrentContext()
[service loadImage:url done:^(UIImage * image){
CGContextDrawImage(context, frame, image.CGImage);
}];
不幸的是,这不起作用。永远不会画出图像。
我也尝试过使用同步连接([NSData dataWithContentsOfUrl:]
),但它会阻塞线程并减少不必要的速度。我不想使用UIImageView。
这样做的正确方法是什么?谢谢!
答案 0 :(得分:3)
我认为正确的方法是预先加载图像,或者在收到图像时通过调用“setNeedsDisplayInRect:”或者在单独的方法中进行自己的绘图处理来绘制图像(iOS可能会阻止您做这虽然,我不确定)。显然,setNeedsDisplayInRect变体需要你手头的图像第二次绘制(缓存它)。
如果您异步加载图像,您的drawRect方法可能会在加载图像之前退出并且绘图焦点不再锁定在drawRect上,因此无法在上下文中绘制图像。您是否尝试设置断点来验证这一点?关于锁定我可能是错的,但我认为我在某些时候读过类似的内容。
答案 1 :(得分:3)
仔细思考 - 为什么会运行?在输入块时,无法保证context
仍然是当前上下文(或者甚至它的后备存储仍然完全有效)。通过使用异步回调,无论是块还是委托方法或其他方法,您都有意将代码推迟到以后的某个时间点。对-drawRect:
的调用已经结束,并且在您输入块之前很久就不在堆栈中了。
答案 2 :(得分:0)
我要尝试的第一件事是确保异步处理程序在主线程上运行:
[service loadImage:url done:^(UIImage * image) {
dispatch_async(dispatch_get_main_queue(), ^{
CGContextDrawImage(context, frame, image.CGImage);
});
}];
如果这没有帮助,我会开始怀疑上下文是否仍然有效。指针是,但上下文可能不是。也许您可以将上下文获取移动到处理程序:
[service loadImage:url done:^(UIImage * image) {
dispatch_async(dispatch_get_main_queue(), ^{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, frame, image.CGImage);
…
});
}];
不确定API是否合理,我不做这样的事情。
答案 3 :(得分:0)
你试过了吗?
__block CGContextRef context = UIGraphicsGetCurrentContext()
[service loadImage:url done:^(UIImage * image){
CGContextDrawImage(context, frame, image.CGImage);
}];
您可能必须对框架执行相同的操作,因此当块返回时,它知道应修改的上下文和框架。