Part1
任何在未来可复用的设计,无形当中可以提高代码质量,这也应该一直是程序员的追求。是否这样设计代码,就是大师和菜鸟的区别。
面向对面思想的深入理解、设计模式的灵活运用,我相信是通往大师之路必要的技能!
OC常用的设计模式:
- 单例模式(Singleton)
- 工厂模式(Factory)
- 委托模式(Delegate)
- 观察者模式(Observer)
- NSNotification
- KVO(Key Value Observing)
- MVC
抽象工厂eg:
适用于iPhone与iPad的VC,不需要关心实现的细节,很nice的思想
@implementation ZOCKintsugiPhotoViewController
- (id)initWithPhotos:(NSArray *)photos
{
if ([self isMemberOfClass:ZOCKintsugiPhotoViewController.class]) {
self = nil;
if ([UIDevice isPad]) {
self = [[ZOCKintsugiPhotoViewController_iPad alloc] initWithPhotos:photos];
}
else {
self = [[ZOCKintsugiPhotoViewController_iPhone alloc] initWithPhotos:photos];
}
return self;
}
return [super initWithNibName:nil bundle:nil];
}
// self = nil的目的是移除ZOCKintsugiPhotoViewController实例上的所有引用,实例(抽象类的实例)本身将会解除分配
初始化方法的设计
Part2
code organization is a matter of hygiene (代码组织是卫生问题)
三元运算符
当三元运算符的第二个参数(if 分支)返回和条件语句中已经检查的对象一样的对象的时候,下面的表达方式更灵巧:
推荐:
result = object ? : [self createObject];
不推荐:
result = object ? object : [self createObject];
Constants 常量
常量应该以驼峰法命名,并以相关类名作为前缀。
这里以SDWebImage举例:
- 局部常量以k打头,eg:
- 全局常量(建议通知名用全局常量)eg:
当你定义你自己的 NSNotification
的时候你应该把你的通知的名字定义为一个字符串常量,就像你暴露给其他类的其他字符串常量一样。你应该在公开的接口文件中将其声明为 extern
的, 并且在对应的实现文件里面定义。
因为你在头文件中暴露了符号,所以你应该按照统一的命名空间前缀法则,用类名前缀作为这个通知名字的前缀。
同时,用一个 Did/Will 这样的动词以及用 "Notifications" 后缀来命名这个通知也是一个好的实践。
Case语句
除非编译器强制要求,括号在 case 语句里面是不必要的。但是当一个 case 包含了多行语句的时候,需要加上括号。
switch (condition) {
case 1:
// ...
break;
case 2: {
// ...
// Multi-line example using braces
break;
}
case 3:
// ...
break;
default:
// ...
break;
}
当在 switch 语句里面使用一个可枚举的变量的时候,default
是不必要的。比如:
switch (menuType) {
case ZOCEnumNone:
// ...
break;
case ZOCEnumValue1:
// ...
break;
case ZOCEnumValue2:
// ...
break;
}
此外,为了避免使用默认的 case,如果新的值加入到 enum,程序员会马上收到一个 warning 通知
当使用 enum
的时候,建议使用新的固定的基础类型定义,因它有更强大的的类型检查和代码补全。 SDK 现在有一个 宏来鼓励和促进使用固定类型定义 - NS_ENUM()
例子:
typedef NS_ENUM(NSUInteger, ZOCMachineState) {
ZOCMachineStateNone,
ZOCMachineStateIdle,
ZOCMachineStateRunning,
ZOCMachineStatePaused
};
参数断言
你的方法可能要求一些参数来满足特定的条件(比如不能为nil),在这种情况下啊最好使用 NSParameterAssert()
来断言条件是否成立或是抛出一个异常。
eg:
相等性
确认我们要比较的是指针还是比较的是对象里真正的值
eg:
利用代码块
一个 GCC 非常模糊的特性,以及 Clang 也有的特性是,代码块如果在闭合的圆括号内的话,会返回最后语句的值
NSURL *url = ({
NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint];
[NSURL URLWithString:urlString];
});
这个特性非常适合组织小块的代码,通常是设置一个类。他给了读者一个重要的入口并且减少相关干扰,能让读者聚焦于关键的变量和函数中。此外,这个方法有一个优点,所有的变量都在代码块中,也就是只在代码块的区域中有效,这意味着可以减少对其他作用域的命名污染。
last
永远不要在 init 方法(以及其他初始化方法)里面用 getter 和 setter 方法
详情看这里http://www.cnblogs.com/wsnb/p/6163377.html
希望会给大家带来帮助(o)/~