iOS中的断言

NSAssert

这个应该都比较熟悉,他的名字叫做“断言”。断言(assertion)是指在开发期间使用的、让程序在运行时进行自检的代码(通常是一个子程序或宏)。断言为真,则表明程序运行正常,而断言为假,则意味着它已经在代码中发现了意料之外的错误。断言对于大型的复杂程序或可靠性要求极高的程序来说尤其有用。而当断言为假的时候,几乎所有的系统的处理策略都是,让程序死掉,即Crash掉。方便你知道,程序出现了问题。

断言其实是“防御式编程”的常用的手段。防御式编程的主要思想是:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。这种思想是将可能出现的错误造成的影响控制在有限的范围内。断言能够有效的保证数据的正确性,防止因为脏数据让整个程序运行在不稳定的状态下面。

关于如何使用断言,还是参考《代码大全2》中“防御式编程”一章。这里简单的做了一点摘录,概括其大意:

用错误处理代码来处理预期会发生的状况,用断言来处理绝不应该发生的状况。

  • 避免把需要执行的代码放到断言中
  • 用断言来注解并验证前条件和后条件
  • 对于高健壮性的代码,应该先使用断言再处理错误
  • 对来源于内部系统的可靠的数据使用断言,而不要对外部不可靠的数据使用断言,对于外部不可靠数据,应该使用错误处理代码。 而在IOS编程中,我们可以使用NSAssert来处理断言。比如:

- (void)printMyName:(NSString *)myName { NSAssert(myName == nil, @"名字不能为空!"); NSLog(@"My name is %@.",myName); }

我们验证myName的安全性,需要保证其不能为空。NSAssert会检查其内部的表达式的值,如果为假则继续执行程序,如果不为假让程序Crash掉。

每一个线程都有它自己的断言捕获器(一个NSAssertionHanlder的实例),当断言发生时,捕获器会打印断言信息和当前的类名、方法名等信息。然后抛出一个NSInternalInconsistencyException异常让整个程序Crash掉。并且在当前线程的断言捕获器中执行handleFailureInMethod:object:file:lineNumber:description:以上述信息为输出。

当时,当程序发布的时候,不能把断言带入安装包,你不想让程序在用户机器上Crash掉吧。打开和关闭断言可以在项目设置中设置assert ,在release版本中设置了NS_BLOCK_ASSERTIONS之后断言失效。

尽可能不要用Try-Catch

并不是说Try-Catch这样的异常处理机制不好。而是,很多人在编程中,错误了使用了Try-Catch,把异常处理机制用在了核心逻辑中。把其当成了一个变种的GOTO使用。把大量的逻辑写在了Catch中。弱弱的说一句,这种情况干嘛不用ifelse呢。

而实际情况是,异常处理只是用户处理软件中出现异常的情况。常用的情况是子程序抛出错误,让上层调用者知道,子程序发生了错误,并让调用者使用合适的策略来处理异常。一般情况下,对于异常的处理策略就是Crash,让程序死掉,并且打印出堆栈信息。

而在IOS编程中,抛出错误的方式,往往采用更直接的方式。如果上层需要知道错误信息,一半会传入一个NSError的指针的指针:

- (void) doSomething:(NSError* __autoreleasing*)error { ... if(error != NULL) { *error = [NSError new]; } .... }

而能够留给异常处理的场景就极少了,所以在IOS编程中尽量不要使用Try-Catch。
(PS:见到过使用Try-Catch来防止程序Crash的设计,如果不是迫不得已,尽量不要使用这种策略)
尽量将没有Crash掉的BUG,让它Crash掉
上面主要讲的是怎么知道Crash的“BUG”。对于合理的制造“BUG”还有一条就是尽量把没有Crash掉的“BUG”,让他Crash掉。这个没有比较靠谱的方法,靠暴力吧。比如写一些数组越界在里面之类的。比如那些难调的多线程BUG,想办法让他Crash掉吧,crash掉查找起来就比较方便了。
总之,就是抱着让程序“死掉”的心态去编程,向死而生。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容

  • 断言(assert) 是指在开发过程是使用的,让程序在运行时进行自检的代码 (通常是一个子程序或宏). 断言为真,...
    MichalWilson阅读 3,175评论 0 0
  • 1.老大要测试30个接口,判断这些接口返回的数据对不对2.保证app在运行的过程中,实时监听数据传递的正确性。2....
    mkb2阅读 415评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,561评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,259评论 25 707
  • 夏至未至的时节,从Suki老师《穿衣有道,品型识人》的小班课走出来,看着天色尚早,天气尚好,身后是意犹未尽的姑娘们...
    卿疯阅读 805评论 18 15