簡體   English   中英

ObjC + Cocoa中的回調

[英]Callbacks in ObjC+Cocoa

我是可可/ ObjC的新手。 有人可以幫我更改代碼以使用異步網絡調用嗎? 當前看起來像這樣(虛構示例):

// Networker.m
-(AttackResult*)attack:(Charactor*)target {
    // prepare attack information to be sent to server
    ServerData *data = ...;
    id resultData = [self sendToServer:data];
    // extract and return the result of the attack as an AttackResult
}

-(MoveResult*)moveTo:(NSPoint*)point {
    // prepare move information to be sent to server
    ServerData *data = ...;
    id resultData = [self sendToServer:data];
    // extract and return the result of the movement as a MoveResult
}


-(ServerData*)sendToServer:(ServerData*)data {
    // json encoding, etc
    [NSURLConnection sendSynchronousRequest:request ...]; // (A)
    // json decoding
    // extract and return result of the action or request
}

請注意,對於每個動作(攻擊,移動等),Networker類都有邏輯來與ServerData進行相互轉換。 期望我代碼中的其他類都可以處理此ServerData是不可接受的。

我需要使A行成為異步調用。 似乎正確的方法是使用[NSURLConnection connectionWithRequest:... delegate:...]實現回調以進行后處理。 這是我可以想到的唯一方法:

//Networker.m
-(void)attack:(Charactor*)target delegate:(id)delegate {
    // prepare attack information to be sent to server
    ServerData *data = ...;
    self._currRequestType = @"ATTACK";
    self._currRequestDelegate = delegate;
    [self sendToServer:data];
    // extract and return the result of the attack
}

-(void)moveTo:(NSPoint*)point delegate:(id)delegate {
    // prepare move information to be sent to server
    ServerData *data = ...;
    self._currRequestType = @"MOVE";
    self._currRequestDelegate = delegate;
    [self sendToServer:data];
    // extract and return the result of the movement
}


-(void)sendToServer:(ServerData*)data {
    // json encoding, etc
    [NSURLConnection connectionWithRequest:...delegate:self] // (A)
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    //json decoding, etc
    switch( self._currRequestType ) {
        case @"ATTACK": {...} // extract and return the result of the attack in a callback
        case @"MOVE": {...} // extract and return the result of the move in a callback
    }
}

但是,這非常難看並且不是線程安全的。 正確的方法是什么?

謝謝,

一種選擇是每個命令/請求有一個對象實例。 另外,您可以使用子類,以便對類型進行多態處理,而不是基於大的switch語句。 使用initWithDelegate:方法(然后在需要參數的命令所對應的子類中具有專門的init)和用於基本發送/接收管道的方法來創建基本命令對象。 每個子類都可以實現handleResponse:或從基類connectionDidFinishLoading:中調用的類似方法。

如果要從該服務的客戶端中隱藏它們,那么Attack:,moveTo:等方法可以隱藏這些對象的實例化,因此客戶端將與同一API進行交互。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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