2010-01-16 65 views
1

我試圖集中我的應用程序的網絡代碼。基本上,在任何需要從服務器獲取信息的地方,我創建一個對象serverRequest來獲取信息。當ServerRequest完成時,它需要將信息發回給調用對象。當然,它應該異步工作 - 我不希望我的應用程序在等待時停下來。集中我的目標C應用程序的網絡代碼

該信息的返回是棘手的部分。看來我的選擇是委派和通知。據我所知,他們都有他們的問題:

代表: 我把自己作爲一個代理傳遞給serverRequest對象。問題是,如果我在請求完成之前解除分配,那麼serverRequest將傳遞一個釋放對象,並且我的程序將崩潰。爲了防止這種情況發生,我將不得不跟蹤所有服務器請求(可能有多個請求),並讓我們在我的dealloc方法中知道所有請求,以便我不會再收到任何消息。所有這些都是可能的,但它確實看起來像一個痛苦。

通知: 似乎有很多工作要傳遞信息。我必須將自己添加爲通知中心的觀察員,然後在我釋放時刪除自己。此外,我必須在ServerRequest中傳遞完成後發佈什麼樣的通知的信息。我的ServerRequest必須將接收到的數據推送到NSDictionary中,然後在傳遞之後將其返回。

這兩種方法都應該可以工作,但它們看起來像是一個非常大的努力,只是讓ServerRequest喚醒調用代碼並將它傳遞給一個對象。我認爲通知有點更靈活,更少一點痛苦,導致崩潰的可能性更小,但我對這兩種方法都不滿意。對於任何反饋,我們都表示感謝。謝謝。

回答

0

您可以保留傳入的委託,然後在服務器請求完成之前不會解除分配。

例如

@interface ServerRequest : NSObject 
{ 
    id delegate; 
} 

@property (retain) id delegate; 
@end 

@implementation ServerRequest 
@synthesize delegate; 
@end 

但你需要避免從另一端釋放ServerRequest,或可以使ServerRequest的引發劑釋放它時,它本身就是釋放,會帶走的問題。要做到這一點

@interface SomeObject : NSObject 
{ 
    ServerRequest getsomedata; 
} 

@property (retain) ServerRequest getsomedata; 
@end 

- (void)f() 
{ 
    [self setGetsomedata:[[ServerRequest alloc] init]]; 
    [[self getsomedata] release]; // take away the refcount from allocating, setting the property will retain 
} 
1

我會去列表方法。只需要一個包含NSMutableArray的requestController來跟蹤所有的請求。這樣做的好處是,當你的控制器被解除分配時,你可以做一些事情,如[請求makeObjectsPerformSelector:@selector(cancelRequest)],以阻止所有這些請求使網絡被佔用。它還有助於調試,因爲實際上您可以詢問每個對象哪些請求有待處理,衡量許多未決請求的性能影響等。請求完成後,可以通知請求控制器,並可以通過簡單的方式將其從列表中刪除的removeObject。

另外,有人必須擁有你的對象。在手動管理的內存中,ObjC對象可以保留它們自己,但是如果你想要移動到GC,擁有一個數組是一個比CFRaining free-floating objects更清潔的解決方案。

0

過去我遇到過類似的問題,但選擇了一個略有不同的設計(類似於@uliwitness的建議。

我選擇將請求(即實際內容)與傳送系統分開。在你的情況下,這意味着serverRequest保存請求的內容(URL,數據等),但不會與服務器進行實際的通信。服務器請求的委託將是一個單例CommLayer類,它實際上負責發送請求,接收請求並向委託人通知請求完成。

所以要發送一個serverRequest,你會打電話給[CommLayer sendRequest:serverRequest withDelegate:myDelegate]。

現在CommLayer是保存委託不serverRequest實際的類,你可以隨時通知CommLayer您的類不再有效使用類似[CommLayer removeDelegate:myDelegate]

當然這更多的工作,但你真的從這個設計中得到很多好處,例如:

  • 網絡流量的真正管理。您可以決定一次打開多少個連接並排隊請求。
  • 您可以取消不需要的請求
相關問題