# 禅与 Objective-C 编程艺术 ## 警告和错误 * 警告 ``` #warning Dude, don't compare floating point numbers like this! ``` * 错误 ``` #warning Dude, don't compare floating point numbers like this! ``` * 让编译器忽略忽略你这段代码的警告 大多数 iOS 开发者平时并没有和很多编译器选项打交道。一些选项是对控制严格检查(或者不检查)你的代码或者错误的。有时候,你想要用 pragma 直接产生一个异常,临时打断编译器的行为。 当你使用ARC的时候,编译器帮你插入了内存管理相关的调用。但是这样可能产生一些烦人的事情。比如你使用 NSSelectorFromString 来动态地产生一个 selector 调用的时候,ARC不知道这个方法是哪个并且不知道应该用那种内存管理方法,你会被提示 performSelector may cause a leak because its selector is unknown(执行 selector 可能导致泄漏,因为这个 selector 是未知的). 如果你知道你的代码不会导致内存泄露,你可以通过加入这些代码忽略这些警告 ``` #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [myObj performSelector:mySelector withObject:name]; #pragma clang diagnostic pop ``` * 忽略没用使用变量的编译警告 ``` #pragma used(foo) ``` ``` - (NSInteger)giveMeFive { NSString *foo; #pragma unused (foo) return 5; } ``` * 善用代码块 一个 GCC 非常模糊的特性、以及 Clang 也有的特性:代码块如果在闭合的括号内,会返回最后语句的值。 ``` self. = ({ NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint]; [NSURL URLWithString:urlString]; }); ``` 这个特性非常适合组织小块的代码,给代码阅读者一个重要的入口且减小相关干扰,能让读者聚焦于关键的变量和函数中,此外这个方法有个优点:变量在代码块的区域内有效,可以减小对其他作用域的命名污染。 * 方法参数断言 你的方法可能需要一些参数来满足特定的条件(比如不能为 nil),在这种情况下最好使用 **NSParameterAssert()**  来断言条件是否成立 括号内的条件为 false 的时候则断言抛出异常 ``` NSParameterAssert(message.length > 0); ``` ``` [self testAssert:nil]; //*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: message.length > 0' - (void)testAssert:(NSString *)message{ NSParameterAssert(!(message.length < 1)); NSLog(@"%@",message); } ```