AFNetworking 踩坑

作者: 郑嘉成_ | 来源:发表于2017-01-20 11:19 被阅读0次

    最近公司的项目把网络库从ASIHTTPRequest 全部替换成了AFNetworking,但是在iOS 7上遇到了频率很高的crash。具体崩溃在AFURLSessionManager.h里的[self.mutableData appendData:data];这一行

    - (void)URLSession:(__unused NSURLSession *)session
              dataTask:(__unused NSURLSessionDataTask *)dataTask
        didReceiveData:(NSData *)data
    {
        [self.mutableData appendData:data];
    }
    

    打印的log

    malloc: *** error for object 0x633c000: pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    

    意思应该是mutableData在某处被释放了,于是查找所有用到mutableData的地方

    - (void)URLSession:(__unused NSURLSession *)session
                  task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error{
    ...
        NSData *data = nil;
        if (self.mutableData) {
            data = [self.mutableData copy];
            self.mutableData = nil;
        }
    ...
    }
    

    在这个回调里mutableData 被释放掉了,但是在iOS 7以上的系统却没发现崩溃,应该是iOS 7里,同一个task,这两个方法是在两个线程异步执行的,导致mutableData 提前置为nil。

    AFNetworking 踩坑

    解决办法

    在操作mutableData的地方加锁,并且加了版本判断,崩溃就基本不会复现了。

    - (void)URLSession:(__unused NSURLSession *)session
              dataTask:(__unused NSURLSessionDataTask *)dataTask
        didReceiveData:(NSData *)data
    {
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
            @synchronized (self.mutableData) {
                if (!self.mutableData) {
                    self.mutableData = [NSMutableData data];
                }
                [self.mutableData appendData:data];
            }
        }else{
            [self.mutableData appendData:data];
        }
    }
    
    - (void)URLSession:(__unused NSURLSession *)session
                  task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error
    {
    ...
        NSData *data = nil;
        if (self.mutableData) {
            data = [self.mutableData copy];
            //We no longer need the reference, so nil it out to gain back some memory.
            if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {//加锁,防止崩溃在[self.mutableData appendData:data];
                @synchronized (self.mutableData) {
                    self.mutableData = nil;
                }
            }else{
                self.mutableData = nil;
            }
        }
    ...
    }
    

    相关文章

      网友评论

        本文标题:AFNetworking 踩坑

        本文链接:https://www.haomeiwen.com/subject/xvpwbttx.html