簡體   English   中英

是否復制了該對象或將其引用轉移到此閉包中? (GCD隊列中的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.

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