# 禅与 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);
}

```
