簡體   English   中英

如何異步drawInRect

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM