HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 通过重试将NSOperation子类化为互联网操作大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我在后台线程中将NSOperation子类化为http post.
那些特定的http帖子不需要返回任何值.

我想要做的是当我出现错误或超时时我希望它在增加延迟后发送(斐波那契).

到目前为止我已经这样做了

NSInternetOperation.h:

#import <Foundation/Foundation.h>

@interface NSInternetOperation : NSOperation
@property (nonatomiC) BOOL execuTing;
@property (nonatomiC) BOOL finished;
@property (nonatomiC) BOOL completed;
@property (nonatomiC) BOOL cancelled;
- (id)initWebservicename:(NSString*)webservicename andPerameters:(NSString*)parameters;
- (void)start;
@end

NSInternetOperation.m:

#import "NSInternetOperation.h"

static NSString * const kFinishedKey = @"isFinished";
static NSString * const kExecuTingKey = @"isExecuTing";

@interface NSInternetOperation ()
@property (strong,nonatomiC) NSString *servicename;
@property (strong,nonatomiC) NSString *params;
- (void)completeOperation;
@end

@implementation NSInternetOperation

- (id)initWebservicename:(NSString*)webservicename andPerameters:(NSString*)parameters
{
    self = [super init];
    if (self) {
        _servicename = webservicename;
        _params = parameters;
        _execuTing = NO;
        _finished = NO;
        _completed = NO;
    }
    return self;
}

- (BOOL)isExecuTing { return self.execuTing; }
- (BOOL)isFinished { return self.finished; }
- (BOOL)isCompleted { return self.completed; }
- (BOOL)isCancelled { return self.cancelled; }
- (BOOL)isConcurrent { return YES; }

- (void)start
{
    if ([self isCancelled]) {
        [self willChangeValueForKey:kFinishedKey];
        self.finished = YES;
        [self didChangeValueForKey:kFinishedKey];
        return;
    }

    // If the operation is not cancelled,begin execuTing the task
    [self willChangeValueForKey:kExecuTingKey];
    self.execuTing = YES;
    [self didChangeValueForKey:kExecuTingKey];

    [self main];
}

- (void)main
{
    @try {
        //
        // Here we add our asynchronized code
        //
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
            NSURL *completeURL = [NSURL URLWithString:[NSString StringWithFormat:@"%@/%@",kWEB_serviCE_URL,self.servicename]];
            NSData *body = [self.params dataUsingEncoding:NSUTF8StringEncoding];
            NSMutableURLrequest *request = [[NSMutableURLrequest alloc] initWithURL:completeURL];
            [request sethttpR_413_11845@ethod:@"POST"];
            [request SETVALue:kAPP_password_VALUE forhttpHeaderField:kAPP_password_HEADER];
            [request sethttpBody:body];
            [request SETVALue:[NSString StringWithFormat:@"%lu",(unsigned long)body.length] forhttpHeaderField:@"Content-Length"];
            [request SETVALue:@"application/x-www-form-urlencoded" forhttpHeaderField:@"Content-Type"];


            if (__iOS_7_AND_HIGHER)
            {
                NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
                NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:[Netroads sharedInstance] delegateQueue:[NSOperationQueue new]];
                NSURLSessionDataTask *dataTask = [session dataTaskWithrequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {
                    if (error)
                    {
                        NSLog(@"%@ Error: %@",self.servicename,error.localizedDescription);
                    }
                    else
                    {
                        //NSString *responseXML = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                        //NSLog(@"\n\nResponseXML(%@):\n%@",webservicename,responseXML);
                    }
                }];
                [dataTask resume];
            }
            else
            {
                [NSURLConnection sendAsynchronousrequest:request queue:[NSOperationQueue new] completionHandler:^(NSURLResponse *response,NSData *data,NSError *connectionError) {
                    if (connectionError)
                    {
                        NSLog(@"%@ Error: %@",connectionError.localizedDescription);
                    }
                    else
                    {
                        //NSString *responseXML = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                        //NSLog(@"\n\nResponseXML(%@):\n%@",responseXML);
                    }
                }];
            }
        });

        [self completeOperation];
    }
    @catch (NSException *exception) {
        NSLog(@"%s exception.reason: %@",__PRETTY_FUNCTION__,exception.reason);
        [self completeOperation];
    }
}

- (void)completeOperation
{
    [self willChangeValueForKey:kFinishedKey];
    [self willChangeValueForKey:kExecuTingKey];

    self.execuTing = NO;
    self.finished = YES;

    [self didChangeValueForKey:kExecuTingKey];
    [self didChangeValueForKey:kFinishedKey];
}

@end

解决方法

几个反应:

>在解决重试逻辑之前,您应该将对[self completeOperation]的调用移到NSURLSessionDataTask或sendAsynchronousrequest的完成块内.您当前的操作类过早地完成(因此不会遵循依赖关系和您的网络操作队列的预期maxConcurrentOperationCount).
>重试逻辑似乎不起眼.也许是这样的

- (void)main
{
    NSURLrequest *request = [self createrequest]; // maybe move the request creation stuff into its own method

    [self tryrequest:request currentDelay:1.0];
}

- (void)tryrequest:(NSURLrequest *)request currentDelay:(NSTimeInterval)delay
{
    [NSURLConnection sendAsynchronousrequest:request queue:[self networkOperationCompletionQueue] completionHandler:^(NSURLResponse *response,NSError *connectionError) {

        BOOL success = NO;

        if (connectionError) {
            NSLog(@"%@ Error: %@",connectionError.localizedDescription);
        } else {
            if ([response isKindOfClass:[NShttpURLResponse class]]) {
                NSInteger statusCode = [(NShttpURLResponse *)response statusCode];
                if (statusCode == 200) {
                    // parse XML response here; if successful,set `success` to `YES`
                }
            }
        }

        if (success) {
            [self completeOperation];
        } else {
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_Now,(int64_t)(delay * NSEC_PER_SEC));
            dispatch_after(popTime,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,^(void){
                NSTimeInterval nextDelay = [self nextDelayFromCurrentDelay:delay];
                [self tryrequest:request currentDelay:nextDelay];
            });
        }
    }];
}

>就个人而言,我对这整个努力都很谨慎.令我感到震惊的是你应该根据错误的类型使用逻辑.值得注意的是,如果由于缺少互联网连接而导致错误失败,则应使用Reachability确定连接并响应通知,以便在恢复连接时自动重试,而不是仅按重复间隔的规定数学级别重试.

除了网络连接(使用Reachability可以更好地解决)之外,我还不清楚其他网络故障是否需要重试逻辑.

一些不相​​关的观察:

>注意,我将main中请求发出的dispatch_async消除到后台队列,因为你已经使用了异步方法(即使你没有,你可能还是把这个操作添加后台队列) .
>我还删除了try / catch逻辑,因为与其他语言/平台不同,异常处理不是处理运行时错误的首选方法.通常,Cocoa中的运行时错误是通过NSError处理的.在Cocoa中,异常通常仅用于处理程序员错误,但不用于处理用户将遇到的运行时错误.请参阅“使用Objective-C编程”指南中的Apple讨论Dealing with Errors.
>如果您只是在各自的声明中为属性定义适当的getter方法,则可以删除手动实现的isExecuTing和isFinished getter方法

@property (nonatomic,readwrite,getter=isExecuTing) BOOL execuTing;
@property (nonatomic,getter=isFinished)  BOOL finished;

>但是,您可能希望编写自己的setExecuTing和setFinished setter方法,如果需要,可以为您执行通知,例如:

@synthesize finished  = _finished;
@synthesize execuTing = _execuTing;

- (void)setExecuTing:(BOOL)execuTing
{
    [self willChangeValueForKey:kExecuTingKey];
    _execuTing = execuTing;
    [self didChangeValueForKey:kExecuTingKey];
}

- (void)setFinished:(BOOL)finished
{
    [self willChangeValueForKey:kFinishedKey];
    _finished = finished;
    [self didChangeValueForKey:kFinishedKey];
}

然后,当您使用setter时,它会为您执行通知,并且您可以删除分散在代码中的willChangeValueForKey和didChangeValueForKey.
>另外,我认为您不需要实现isCancelled方法(因为已经为您实现了).但是你真的应该覆盖一个调用其超级实现的cancel方法,但是也会取消你的网络请求并完成你的操作.或者,您可以移动到基于委托的网络请求再现,而不是实现取消方法,但请确保在didReceiveData方法中检查[self isCancelled].

并且isCointed让我觉得与isFinished一样多余.看起来你可以完全消除已完成的属性和isCompleted方法.>您可能通过支持NSURLSession和NSURLConnection来不必要地重复网络代码数量.如果你真的想要,你可以这样做,但他们向我们保证NSURLConnection仍然受支持,所以它让我觉得不必要(除非你想要享受iOS 7设备的一些NSURLSession特定功能,你目前没有这些功能).做任何你想要的,但就个人而言,我正在使用NSURLConnection,我需要支持早期的iOS版本,而NSURLSession,我不需要,但我不会倾向于实现它们,除非有一些令人信服的业务要求这样做.

大佬总结

以上是大佬教程为你收集整理的ios – 通过重试将NSOperation子类化为互联网操作全部内容,希望文章能够帮你解决ios – 通过重试将NSOperation子类化为互联网操作所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。