回调在ObjC +可可
问题描述:
我是比较新的可可/ ObjC。有人可以帮我改变我的代码来使用异步网络调用吗?目前,它看起来像这样(例如虚构):回调在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:...委托:...]实施回调做后期处理。这是我能想到的唯一方法:
//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:中调用的类似。
如果要隐藏,从这个服务,你的攻击:,的moveTo:等的客户方法可以隐藏这些对象的实例化,所以客户端将与相同的API进行交互。
你能告诉我有什么好处呢对任何人你的代码的一个虚构的例子吗?我不得不说,这与把你的邻居的车带到机械师差不多,因为你的东西有问题。 – Sneakyness 2009-07-26 18:50:34
使用简单的游戏比喻更容易说明我的设计问题,而不是解释我正在开发的应用程序的某些复杂功能。 – tba 2009-07-26 19:06:27