David Hu David Hu - 5 months ago 9
Objective-C Question

Why it still call block after I quit my viewcontroller

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);
}
}];
}

Answer

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
         }
    }];