Search code examples
iosobjective-cnetwork-programmingafnetworkingblock

Don't call callback block after exiting view controller


When I build my app, I create a Class called NetEngine to manage all the network request. But I find that after I quit a view controller which use NetEngine, I still call the success or failure block.

viewcontroller:

    [[NetEngine engine] GET:httpUrl success:^(id responseObject) {
         //some code here
         //It's still called after I quit viewctroller
    } failure:^(NSError *error) {
         //some code here
         //It's still called after I quit viewctroller
    }];

NetEngine:

typedef void(^SuccessBlock) (id responseObject);
typedef void(^FailureBlock) (NSError *error);

@interface NetEngine ()

@property (nonatomic, strong) AFHTTPSessionManager *httpManager;

@end

@implementation NetEngine

+ (NetEngine *)engine {
    static NetEngine *_sharedEngengine = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedEngengine = [[self alloc] init];
    });

    return _sharedEngengine;
}

- (id)init {
    if (self = [super init]) {
        _httpManager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:BZTVBaseServerPath]];
        [_httpManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"accept"];
        _httpManager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
        _httpManager.operationQueue.maxConcurrentOperationCount = 4;
        [_httpManager.requestSerializer setTimeoutInterval:10.0];
    }
    return self;
}

- (void)GET:(NSString *)URLString success:(SuccessBlock)successBlock failure:(FailureBlock)failureBlock {
    // some thing about cache

    [_httpManager GET:encodeUrl parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        [[self defaultCache] setObject:responseObject forKey:cacheKey];
        if (successBlock) {
            successBlock(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (isCache) {            
            if (successBlock) {
                successBlock([[self defaultCache] objectForKey:cacheKey]);
            }
        }
        if (failureBlock) {
            failureBlock(error);
        }
    }];
}

Solution

  • If you want to cancel the network call when you quit your view controller, here's what you have to do :

    Create a cancel BOOL variable

    Add a viewWillDisappear method :

    -(void) viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
    
        cancel = YES;
    }
    

    Check if cancel is YES in callback method :

       [[NetEngine engine] GET:httpUrl success:^(id responseObject) {
             //some code here
             //It's still called after I quit viewctroller
             if (!cancel) {
                //do what you have to do
             }
        } failure:^(NSError *error) {
             //some code here
             //It's still called after I quit viewctroller
             if (!cancel) {
                //do what you have to do
             }
        }];