2014-01-18 90 views
0

使用釋放我有其中有幾個視圖控制器的IOS項目(ARC禁用)。一個特定的控制器初始化MyClass類型的成員對象,但是當視圖控制器被解散時,我爲使用線程的對象(使用dispatch-async)調用一個清理方法來做一些耗時的操作,然後當這些操作在對象的主隊列上執行[自釋放]完成。這是一個很好的做法,會導致任何錯誤嗎?下面是一個類似的例子,以什麼即時做:IOS在一個異步塊

@implementation ViewController 

- (void)viewDidLoad 
{ 
    myObj = [[MyClass alloc] init]; 
} 

-(void)viewWillDisappear 
{ 
    [myObj cleanup]; 
} 

@end 

//myClass 
@implementation MyClass 

- (void)cleanup() 
{ 
    dispatch_queue_t myQueue = dispatch_queue_create ("MyClassDeallocQueue", NULL); 
    dispatch_async(myQueue, ^{ 
     //time consuming operations   

     dispatch_async(dispatch_get_main_queue(), ^{ 
     [self release]; 
     }); 
    }); 

} 

@end 
+1

我不這樣做手工引用計數,但不會塊有你的對象的引用?所以你可以調用清理函數,然後立即從控制器內部釋放它。 '[self release]'對我來說似乎是錯誤的... – Putz1103

+0

你可能以前聽說過這個,但是ARC很棒。它比人工計數好得多。它只花了幾個小時將我們的大應用程序轉換爲它。 – HalR

+0

Pulz1103,我不能調用立即釋放,這個對象需要清理它可以釋放 – user157453

回答

0

這是一個很好的做法,會不會引起任何錯誤?

目前,你的代碼中有一個不平衡的保留/釋放。這絕對是一個錯誤(超過發佈)。

「是不是好的做法呢?」 - 呃,我不知道你在做什麼。但是如果你的目標是保持self存活,直到塊被執行後,它已經完全通過self將被捕獲的事實來完成。所以,嚴格來說不需要release

但是,如果沒有明確在主線程釋放self,你介紹個微妙的問題:它可能發生在塊具有最後參考self,由於它可能對某些任意線程執行,它會在這個非主線程上釋放self。這是禁止的:必須在主線程上調用UIKit方法(包括dealloc)!

因此,它可能是有意義:

[self retain]; 
    dispatch_async(myQueue, ^{ 
     // time consuming operation, which captures `self`   
     [self doSomething]; 
     ... 
     // ensure that `dealloc` will be executed on the main thread, if 
     // last reference is held by the block: 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self release]; 
     }); 
    }); 

或更短:

dispatch_async(myQueue, ^{ 
     // time consuming operation, which captures `self`   
     [self doSomething]; 
     ... 
     // ensure that `dealloc` will be executed on the main thread, if 
     // last reference is held by the block: 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self self]; 
     }); 
    }); 

編輯:

這是一個有趣的問題,無論是 「短」 的版本實際上是踩着-safe或有種族:

增刊OSE,self將在上myQueue中執行的塊被釋放,作爲捕獲self之前的效果將是在相同的保留的博克作爲捕獲self用於在主隊列中執行的塊的效果。然後,我們有一個問題。評論贊賞。