IOS常见错误合集

IOS常见错误合集

做IOS开发也快3年了,跳了不少坑,也刨了不少坑,这篇就讲讲这些年来常见的坑。我把常见错误,根据表现出来的时机分为三类,分别对应开发时、编译时、运行时。本文列举了这些常见错误,简单解析了错误的原因,并且提供了大致的解决方案。

开发时

开发时错误,如果编辑器能直接定位到代码上,就很好排查。比如分号漏写,方法名错误等。还有一些是逻辑错误,编辑器不给提示,这种问题就很难排查。这种类型的问题,相信大家都遇到过,也有自己的一套经验,所以就不细说。以下稍微列举了一些开发时错误:


语法错误

问题描述:语法错误就不细说了。

    //初始化数组语句后面少分号
    NSArray *arr = [NSArray array]

    //for循环后面多了一个分号
    for (int i = 0; i < arr.count; i++); {

    }

    //break丢失
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    switch (btn.state) {
        case UIControlStateNormal: {

        }
            break;
        case UIControlStateDisabled: {

        }
        case UIControlStateSelected: {

        }
            break;
        default:
            break;
    }

解决方案:养成良好的编码习惯,多用IDE环境的代码补全,比如for循环,就直接让IDE把for循环的结构补全出来。switch结构就先把外层的结构写全,再慢慢补充里面的逻辑代码。


方法名错误

问题描述:OC的方法名都很长,恨不得把功能都描述完整,这是好事,但是调用方法的时候就很累,尤其OC还区分大小写,一不小心方法名就写错了。这个问题初学者尤其常见。比如以下例子:

    //正确的方法
    UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:@"呵呵" otherButtonTitles:nil];

    //错误写法,title的t没有大写
    UIAlertView *alert2 = [[UIAlertView alloc] initWithtitle:nil message:nil delegate:self cancelButtonTitle:@"呵呵" otherButtonTitles:nil];

解决方案:善用IDE环境的代码补全功能,尽量不要手写整个方法,而是通过tab键加部分字母来补全,和命令行敲路径非常相似。


ARC和MRC文件混用

问题描述:在MRC环境下,代码里会用到release,autorelease等关键字,在ACR环境下是禁用的,同样在MRC下,ARC环境的strong,weak等,也无法使用。强行使用会直接报错。
这里写图片描述
解决方案:在工程对应的TARGET下,选择Build Phases,Complie Sources,找到对应的文件,双击,补上-fno-objc-arc 或者 -fobjc-arc ,前者是在ARC工程用MRC的文件,后者反之。
这里写图片描述


编译时

有的工程,在编码阶段一片祥和,然而,command+b编译,就抛出错误,这些问题就归到编译错误里。由于在编译的时候,会有一些诸如引用静态库的操作,所以有的编译时错误非常难查。以下是我遇到过的一些编译时错误:


重复定义

关键字:duplicate
问题描述:这个问题就是我们常说的冲突,比如,有一些常见的开源库,AFNetwrok,ASIHttpRequest,大家都用,当大家同时引入这同一个开源库,就很容易出现重复定义的问题。这里举的例子是全局变量和类名冲突,其他的还有各种形式的冲突,不一一列举。
这里写图片描述
上图所示,就是两个库,分别在AASIHTTPRequet和TRHTTPRequest都定义了_NetworkRequestErrorDomain,导致重复定义。
这里写图片描述
上图所示,自己定义了UIView和UIKit系统库里的UIView冲突了。
解决方案:既然是冲突,就得有人让步:
第一种情况,很不巧,这两个库一个封装成.a,一个封装成framework,你如果没办法改动源码,只能联系开发人员修改变量名字了。所以我们自己在封装库的时候,尽量别用那种很通用的类名以及全局变量。
第二种情况这种类名冲突就好办了,代码可见,而且定位准确,直接修改即可。


证书、描述文件错误

关键字:Code Sign
问题描述:苹果的真机调试,发包,需要使用证书和描述文件(现在真机调试不用证书了,以前要的,具体哪个版本开始不需要我忘了),选错或者没选的话,就会报错。
提示的错误
如上图所示,证书、描述文件错误的提示已经很明显了:直接译过来就是没找到匹配的配置文件。
解决方案:
修改的位置
我们需要选择蓝色的工程文件,选择对应的Target,选择Build Settings,找到Code Signing选项,
这里写图片描述
把证书、描述文件改成你对应的选项就好了。


支持库缺失

关键字:not found
问题描述:
这里写图片描述
这种情况是调用别人封装好的库,但是系统支持库没有导进来的情况。至于缺失什么系统库,需要查文档,或者根据错误信息的名字去搜索。比如上图缺失了一个ASIdentifierManager类,在搜这个类,一般就能查询到是缺了AdSupport库。
解决方案:
这里写图片描述
如上图所示,引入缺失的库即可。
这里写图片描述
还有一种情况,如上图所示,缺失的是一个三方库,这个时候就要看三方库是否真的有,如果有这个三方库才能进行引用。


指令集不支持

关键字:No architectures to compile
问题描述:常用的指令集有i386,x86,armv7,armv7s,arm64,不同设备需要对应的指令集支持。
这里写图片描述
如上图所示,某些库,只支持armv7和arm64,那就不能在虚拟机上使用。
这里写图片描述
这里写图片描述
还有一种情况是设置问题,Architechures和Valid Architechures两项的交集,才是可以使用的指令集,上图就是两者没有交集,导致的编译失败。

解决方案:第一种情况,只能找对应库的开发人员提需求,第二种情况,需要根据具体情况,让Architechures和Valid Architechures两项有交集。


资源格式错误

关键字:CopyPNGFile
问题描述:开发中,我们一般用png格式的图片,有时候手里只有jpg格式的图片,就想说改下后缀好了(幼稚),编译的时候就会报找不到xxx.png图片的错误。
这里写图片描述
解决方案:老老实实用PS等工具来进行图片格式的转化,别想着改个后缀就来忽悠苹果。


混编

问题描述:有的时候,我们可能需要在OC的工程里,引入CPP的库,如果直接引入,编译器是不认的。会直接在代码里报错或者编译的时候报错:
这里写图片描述

这里写图片描述

解决方案:把引用CPP的库的文件后缀改成.mm,然后到工程,对应的TARGET,Build Setting,里找到C++ Standard Library选项,改成libc++或者通过文件后缀来识别。如下图所示:
这里写图片描述


系统框架误修改

问题描述:曾经,我们调用系统库的方法时候,经常会用command+左键,跳转到指定方法里,查阅接口的注释。但是,偶尔会不小心,改到系统库文件,导致整个编辑器里都是error。今天我尝试着修改系统库文件,提示我被锁定,并且无法解锁,看来苹果对这块也在做改进,这里就不上图了。
解决方案:从别的设备上拷一份framework,把损坏的framework替换掉。


运行时

运行时错误,顾名思义,就是编译成功后,运行之后出现的问题,或者是某个事件触发,又或者是运行时间到一定程度以后触发的错误。


调用了不存在的方法

关键字:unrecognized selector
问题描述:出现unrecognized selector类型的crash,一般是向对象发送了无法处理的消息导致的。说白一点就是这个对象没有你调的那个方法,为什么运行的时候才会出现,这个和OC语言动态绑定的机制有关系。下图所示,是向一个NSNumber的对象发送NSString的方法。

id num = [NSNumber numberWithInt:123];
[num UTF8String];

这里写图片描述
解决方案:在调用方法之前,检查消息接受者的类型,或者干脆判断一下是否能响应这个消息。常见的方法有,isKindOfClass,respondsToSelector等,总之就是遵循有备无患的原则。

数组越界

问题描述:数组越界这个就没啥好说的了,你都跑别人的地盘去了,OC不像C语言那样还能弄点意外惊喜,OC会直接给你crash。

    NSMutableArray *arr = [NSMutableArray arrayWithObjects:
                           @"111",
                           @"222",
                           @"333",
                           @"444",
                           @"555",
                           nil];
    [arr objectAtIndex:10];

这里写图片描述
解决方案:多用数组的count方法,比如循环的时候,可以判断下标和count。

快速枚举的时候移除元素

问题描述:快速枚举的时候对容器进行了增减操作等。

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"111",@"222",@"333",@"444",@"555", nil];

for (NSString *str in arr) {
    if ([str isEqualToString:@"222"]) {
        [arr removeObject:str];
    }
}

这里写图片描述
解决方案:要么就别乱改,如果真需要改,就不要用快速枚举了,用传统的for循环。

向容器存入nil

问题描述:OC的容器(数组,字典,集合)是不允许放入nil的,但往往事与愿违,不经意间会把nil丢到容器里。

    NSMutableArray *arr = [NSMutableArray arrayWithObjects:
                           @"111",
                           @"222",
                           @"333",
                           @"444",
                           @"555",
                           nil];
    [arr addObject:nil];

这里写图片描述
解决方案:在把元素存入容器的时候,判断一下元素是否为nil,如果非要放一个空元素的话,NSNull是个不错的选择。


资源缺失

问题描述:有的时候,某个页面明明放了一个图标,但是运行起来一看,图标不见了。
解决方案:查询资源是否有导入mainBundle,UIImage的imageNamed方法,是从mainBundle里获取资源的。这种问题比较好处理,所以也就不细说了。


内存泄露

问题描述:在MRC的环境下,比较容易出现引用计数配不平导致的内存泄露,然而现在大部分环境都是用的ARC了,所以更多的需要关注诸如循环引用,间接访问误修改这类问题。这种问题就相当难查了,只能用一些工具,看内存使用是否有异常等。

解决方案:xcode的profile里有一款Leaks工具,专门用来测内存的。这里也就不细说了,类似教程也很多。
这里写图片描述


动画重复

关键字:Attempt to
问题描述:动画重复,就是上一个动画还在进行的时候,又去执行下一个动画,这样会出现一些卡顿之类的灵异事件。

for (int i = 0; i < 2 ; i++) {
    MyVC *myVc = [[MyVC alloc]init];
    [self presentViewController:myVc animated:YES completion:^{

    }];
}

这里写图片描述
解决方案:在上一个时间的动画结束回调里,再去执行下一个动画。

总结

实际开发过程中,坑远远不止这些,所谓前人挖坑,后人来填,把这些常见错误写出来,只是希望掉坑的人姿势好一些,也希望自己别掉坑,欢迎大家在评论里补充。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值