IOS菜鸟初学第十篇:处理NSURLSessionDataTask的返回值引起的程序崩溃问题

昨天被标题的bug搞了一上午,总算在一位大佬的指点下顺利解决问题。

首先贴一下我是怎么出现在这个bug的

我想根据请求服务器后台返回的未读消息数量,动态设置底部分栏控制器的角标

于是就有了下面的代码

运行的时候报错 unrecognized selector sent to instance 0xxxxxxxxxxx

一开始我以为这里面不能用self

后来经过大佬的分析

应该是返回的数据引用有问题

数据类型不对

服务器返回的是json,如下

{"status":1,"num":1}

我这里用 NSJSONSerialization解析json数据

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

解析出来的数据是字符串,但是!!!

字符串也分长(long)短型,还有什么无符型等等,我贴一个网上的说明

所以,我使用dict[@"status"]和dict[@"num"]时都要转成正常的string或者integer

所以最后我的代码就变成这样

__weak __typeof(&*self)weakSelf = self;
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            //NSLog(@"返回结果%@",response);
     if (error == nil) {
           //6.解析服务器返回的数据
           //说明:(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)
           NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            
           NSString * num = dict[@"num"];
           if([dict[@"status"] integerValue] >0){
                NSLog(@"判断生效");
                dispatch_async(dispatch_get_main_queue(), ^{
                    weakSelf.navigationController.tabBarItem.badgeValue = dict[@"num"];
                }
            }else{
                NSLog(@"推送错误:%@",error.userInfo);
            }
        }];

解释一下里面涉及的三个注意点:

现通过[dict[@"status"] integerValue] 将dict[@"status"]转成int类型作为判断条件。

dispatch_async(dispatch_get_main_queue(), ^{}这个方法是返回主线程设置角标,如果不返回主线程就会在控制台发出警告([Animation] +[UIView setAnimationsEnabled:] being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior.),但是程序并不会崩溃。

这里为什么会用到 __weak __typeof(&*self)weakSelf = self;呢 。我们在datatask(block中)直接使用self是不可取的。因为block会copy它内部的变量,可能会造成引用循环,使用__weak性质的self替代self,可以切断block对self的引用,避免循环引用。typeof(self) 是获取到self的类型,这样定义出的weakSelf就是和self一个类型的, 加上__weak是建立一个若引用,整句就是给self定义了一个若引用性质的替身;

至于你如果遇到这样情况,可参考一下,先将json数据format,无论是否一开始对不对,还是建议先转一下。其次不要直接使用self。用弱引用。

发布了65 篇原创文章 · 获赞 31 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/zhangtao0417/article/details/90764746