[英]How to drawInRect asynchronously
我正在嘗試從一個URL加載一個巨大的圖像(約131.072x131.072像素),並將其很好地平鋪為256x256像素的512x512拼貼。
函數返回圖像后,我想將其繪制在Rect中的適當位置。
由於此過程需要一段時間,因此我想異步運行整個過程。 以下是我到目前為止嘗試過的方法:
override func drawRect(rect: CGRect) {
let firstColumn = Int(CGRectGetMinX(rect) / sideLength)
let lastColumn = Int(CGRectGetMaxX(rect) / sideLength)
let firstRow = Int(CGRectGetMinY(rect) / sideLength)
let lastRow = Int(CGRectGetMaxY(rect) / sideLength)
let qos = Int(QOS_CLASS_USER_INITIATED.rawValue)
dispatch_async(dispatch_get_global_queue(qos, 0)) { () -> Void in
for row in firstRow...lastRow {
for column in firstColumn...lastColumn {
let url = NSURL(string: "https://someURL/\(row)/\(column).jpg")
let tile = UIImage(data: NSData(contentsOfURL: url!)!)!
let x = self.sideLength * CGFloat(column)
let y = self.sideLength * CGFloat(row)
let point = CGPoint(x: x, y: y)
let size = CGSize(width: self.sideLength, height: self.sideLength)
var tileRect = CGRect(origin: point, size: size)
tileRect = CGRectIntersection(self.bounds, tileRect)
dispatch_async(dispatch_get_main_queue()) {
tile.drawInRect(tileRect)
}
}
}
}
}
我收到此錯誤:
<Error>: CGContextRestoreGState: invalid context 0x0. Backtrace:
<-[UIImage drawInRect:]+66>
<_TFFFC6H1Z1DB15MyClass8drawRectFS0_FVSC6CGRectT_U_FT_T_U_FT_T_+122>
<_TTRXFo__dT__XFdCb__dT__+39>
<_dispatch_call_block_and_release+12>
<_dispatch_client_callout+8>
<_dispatch_main_queue_callback_4CF+1738>
<__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__+9>
<__CFRunLoopRun+2073>
<CFRunLoopRunSpecific+488>
<GSEventRunModal+161>
<UIApplicationMain+171>
<main+109>
誰能給我一個關於如何異步檢索和繪制圖像的提示嗎?
不要使用drawRect
。 在這種情況下,沒有理由使用drawRect
。 只需使用視圖,圖層,SpriteKit或OpenGL ES(可能還有更多可能的選擇)。 在前兩種情況下,您可能必須根據在屏幕上可見的視圖部分添加/刪除位和片段,但是使用標准視圖/圖層將為您帶來更好的性能。 蘋果強烈建議您不要使用drawRect
。
如果確實使用drawRect
,那么一定不要在其中加載數據。 蘋果明確指出,您應該在其中進行繪制 ,而不要在此處進行任何其他操作。 而且您當然不希望在其中啟動異步任務,這只會導致災難。 預先加載數據,將其存儲在某個地方,然后在drawRect
進行繪制。 如果在用戶移動時加載數據,請在用戶移動時加載數據,而不是在繪制時進行。 實際加載圖像后,您可能需要使rect無效,以便隨后調用drawRect
。 但是同樣,不要使用drawRect。 只需添加/刪除視圖/圖層。
我也建議不要使用NSData(contentsOfURL:)
。 將NSURLSession
dataTask*
與適當的完成處理程序一起使用。 這樣,您的所有負載將同時發生(達到設置的限制),而不是一個接一個地發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.