[英]Objective-c (iphone) best practice service data dispatching
我正在努力设计服务获取模式
到目前为止,我已经提出了:
ServiceCaller(这是客户端将使用的唯一类,它具有用于访问Web服务的特定部分的所有方法,例如requestHello,requestLogon,requestUserDetails等。)
ServiceConnector(此类在服务调用方中实例化,该类将与服务器进行实际连接以请求数据,并将其返回给需要将其分派回客户端的调用方,在服务连接器中,我使用抽象工厂模式以分离请求逻辑,并确定需要解析的Web服务的哪一部分)
我面临的问题是我将如何处理向客户的调度。 我正在考虑使servicecaller为单例,因此它只有1个servicecaller实例,因此只有1个service连接器实例,但是将其保持打开状态以同时与服务器建立多个连接。 并使用委托属性处理回调
但是,例如当在两个单独的视图中完成2次调用时,我更改了proxy属性,这意味着只有最后执行的调用才收到他的回调,而另一方则没有。
有人知道我该如何解决这个问题?
一种方法是将委托模式替换为另一种回调模式:延续样式。 这个想法是让您的API将延续块作为参数。 完成工作后,只需调用continuation块即可。 这是API过程的示例:
typedef void(^ContinuationBlock)(id result, NSError *error);
- (void) answerTheDefinitiveQuestion:(Towel *)h2g2Towel do:(ContinuationBlock*) continuation
{
if (h2g2Towel) {
double answer = 7 / h2g2Towel.length * (sqrt(h2g2Towel.area+2*h2g2Towel.area+1) - 1) * 6 / h2g2Towel.width;
continuation([NSNumber numberWithDouble:answer], nil);
} else {
NSError *err = [[[NSError alloc] initWithDomain:H2G2Domain code:kMissingTowel userInfo:nil] autorelease];
continuation(nil, err);
}
}
现在,客户端可以以这种方式使用它:
- (void) doSomething
{
[myServiceCaller answerTheDefinitiveQuestion:self.towel do:^(NSNumber * answer, NSError *error) {
if (!answer) {
NSLog("No answer available because %@, %@", error, error.userInfo);
} else {
NSLog("haha, Zaphod, your answer is %@, %@", answer);
}
}];
}
注意:此示例是同步的,但在异步上下文中也可以正常工作。 例如,您可以在对dispatch_async
的调用中加入answerTheDefinitiveQuestion:do:
的实现。
实际上,这种方法非常适合于全异步API。 唯一要记住的是,如果存储了以后要调用的continuation块,则必须存储一个副本,因为获取的该块是基于堆栈的,并且在函数返回时将消失。 只需做:
self.myClientContinuation = [continuation copy];
PS:整个单例想法都是邪恶的。 至少在您的设计中,ServiceCaller似乎没有任何意义(与ServiceConnector相对)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.