2013-08-06 67 views
3

想象三個類。 ClassA和ClassB是我的。第三類是一個UIViewController其代碼我不能修改:如何最好地保留委託給ARC的自我?

在ClassA的:

- (void) aMethod 
{ 
    ClassB *classBInstance = [[[ClassB alloc] init] goWithOptions:options]; 
} 

ClassBInstance保留只爲aMethod壽命。

在ClassB的:

- (void) goWithOptions 
{ 
    AUIViewController *avcInstance = [[AUIViewController alloc] init]; 
    avcInstance.delegate = self; 
    [viewController pushViewController:avcInstance animated: YES]; // this returns immediately, but we need self to be retained until the delegate is done with it 
} 

- (void) cleanupCalledByDelegate // 
{ 
    // cleanup 
} 

-goWithOptions方法被調用,avcInstance由被叫方保留,但自,其被傳遞給delegate不是。這意味着只要-goWithOptions返回,並且aMethod完成,那麼classBInstance被釋放,並且delegate對於avcInstance不再有效。

理想情況下,我想將classBInstance(自己在ClassB中)的所有權與avcInstance;當avcInstance獲得釋放時,則classBInstance或委託人被釋放。

或者,我可以清除classBInstance中的 - cleanupCalledByDelegate,這是在avcInstance發佈之前調用的。

如何最好地處理這個問題?我寧願不將ClassB *classBInstance作爲ClassA的一個屬性,因爲那樣我就不得不讓它釋放classBInstance,我寧願在ClassB中處理它。如果這是最好的解決辦法,我會用蓋帽和ClassA的,通過完成塊:

{ 
    classBInstance = nil; 
} 

-goWithOptions,我會在-cleanupCalledByDelegate調用。這是處理這個問題的正確方法嗎?

+0

弧的缺點之一是你沒有太多的控制。保留/釋放現在綁定到屬性。要保留/發佈某些內容,您必須添加其他媒體資源。 –

+0

@JustinMeiners - 不只是屬性。強大的艾瓦爾,範圍和協會。 – TomSwift

+0

@TomSwift對,就是說,它現在綁定到一個命名變量,這使得解決這類問題變得更加麻煩。 –

回答

5

如果你只是想「扎classBInstance(個體經營在ClassB的),以avcInstance的所有權」,你可以使用Objective-C的對象關聯:

#import <objc/runtime.h> 

objc_setAssociatedObject(avcInstance, "my_association", classBInstance, OBJC_ASSOCIATION_RETAIN); 

此外,如果你需要更多的方便訪問classBInstance稍後可以將此關聯代碼封裝到類別擴展中,該擴展將classBInstance作爲avcInstance上的一個屬性公開。

+1

你可以做到這一點(+1),但它聞起來像糟糕的應用程序設計。如果ClassA與標準弱代表需要與ClassB更正式的關係,那麼它應該被建模爲更加正式的關係並且被明確地管理。 – bbum

+0

但是,難道不是ClassB需要與picker更正式的關係嗎? A班只是想要一些班級來完成一項任務,並不想被這種方式困擾。 B類是需要將自身與UIViewController選擇器連接起來的類,它需要委託並且不保留委託。 – mahboudz

+0

例如,ClassA想要顯示一些信息。它並不在乎它如何顯示,或者顯示是否成功。它打個電話,順其自然。實際上,ClassA可能希望進行許多顯示調用,並假定ClassB將管理隊列 - 這意味着ClassA中的單個屬性不是答案,我們要麼依賴在堆棧上創建唯一實例,要麼創建並數組屬性來跟蹤ClassB實例。 – mahboudz

相關問題