![](/img/trans.png)
[英]Block in serial dispatch queue not executing - GCD iOS Objective-C
[英]Is this object copied or is its reference carried over into this closure? (Objective-C block in a GCD queue)
我對Objective-C和iOS編程比較陌生(最近才在這種環境下更認真地進行編程)。 因此,我試圖更好地處理來龍去脈。
所以,也就是說,我在下面有這段代碼,在這里我獲取視圖的內容並將這些內容編碼為Base64字符串。 如您所見,我創建了這些位的副本,因為在此塊工作時,該層很可能會看到更改。 這是我為避免任何沖突所做的嘗試。
CGImageRef imageRef = CGImageCreateCopy((__bridge CGImageRef)self.interactiveLayer.layer.contents);
dispatch_async(self.mySerialWorkerQueue, ^{
@autoreleasepool {
if (imageRef) {
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
NSData *contentsData = UIImagePNGRepresentation(image);
NSString *encodedContents = [contentsData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
...
所以問題是, CGImageCreateCopy
冗余? 如果我只是簡單地執行以下操作:
CGImageRef imageRef = (__bridge CGImageRef)self.interactiveLayer.layer.contents;
...閉包是否掛在對該數據的引用上,還是會創建基礎數據的本地副本?
附帶說明一下,如果有人對改進工作本身有建議(例如直接對BaseImage編碼CGImage進行編碼),我將不勝感激!
提前致謝。
創建塊時,塊將復制其捕獲的任何(非__block
)變量的值。 復制該塊時,它將1)保留任何對象指針類型的已捕獲變量,以及2)對於塊指針類型的已捕獲變量,還將對其進行復制。
CGImageRef
不是Objective-C對象指針類型,因此將無法對其進行任何內存管理。 創建塊時,將復制變量( imageRef
,CGImage結構的指針)的值( =
)。 而已。 如果要確保CGImage對象在塊執行時仍保持活動狀態,則需要以某種方式保留它,並在不再需要時釋放它。
您可以執行的一種方法是在其上執行CFRetain
(或CGImageRetain
)。 然后在完成該塊時執行CFRelease
(或CGImageRelease
)。 問題在於,沒有什么好方法可以檢測出何時“完成”了該塊。 您可以將發行版放在塊的末尾,在這種情況下將可以使用,因為我們知道dispatch_async
將只執行一次該塊。 但這通常是不好的,因為您發布的內容范圍與保留范圍不同。 如果該塊根本不運行,則將是泄漏; 如果該塊運行了不止一次,它將被過度釋放。
使該塊保留CGImage對象的另一種方法是將CGImageRef
轉換為Objective-C對象指針類型(例如id
),然后讓該塊捕獲該對象。 這樣,該塊將在復制該塊時保留它,並在釋放該塊時釋放它,就像使用普通的Objective-C對象指針一樣。
“復制”與保留不同。 至於是否需要CGImageCreateCopy
; 這取決於您是否需要單獨的副本。
實際上,我想到可以對此進行測試(duh),並且觀察到的是,一旦在塊內,內存地址就保持不變。 因此,確實似乎是對內存中相同位置的引用是被繼承的(有意義的)。 所以看起來CGImageCreateCopy
是我這里要解決的問題。
如果可能對某人有幫助,我將不予理會,但是對此的任何確認都是很好的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.