繁体   English   中英

Objective-C(iPhone)最佳实践服务数据调度

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM