iphone - ObjC+Cocoa 中的回调

标签 iphone objective-c cocoa events refactoring

我对 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 是 Not Acceptable 。

我需要使 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: 方法创建一个基本命令对象(然后在与需要参数的命令相对应的子类中专门初始化)和基本发送/接收管道的方法。每个子类都可以实现一个handleResponse: 或类似的从基类connectionDidFinishLoading: 调用的函数。

如果您想对此服务的客户端隐藏这一点,您的attack:、moveTo:等方法可以隐藏这些对象的实例化,因此客户端将与相同的API交互。

关于iphone - ObjC+Cocoa 中的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1185235/

相关文章:

iphone - 应用程序处于后台状态时的 CLLocationManager

javascript - 使用包含 .js 和 .css 文件的嵌入式 URL 加载 webview

iphone - iOS : How to Copy One User Define Model Class to Another Object of It's type

iphone - 将 UIView 添加到另一个 UIView 作为 SubView

objective-c - 如何在其他线程上对我的方法回调进行排队?

objective-c - dispatch_async 中的 NSManagedObjectContext PerformBlock

iPhone 和 HMAC-SHA-1 编码

iphone - 如何更改 UIPageControl 点

cocoa - 首次启动时将文件安装到应用程序支持中

swift - 程序终止后重新打开 Finder 窗口