美文网首页
Effective Objective-C 2.0 编写高质量i

Effective Objective-C 2.0 编写高质量i

作者: 携一两本单色书来 | 来源:发表于2019-03-09 17:06 被阅读0次

第一章 熟悉Objcetive -C

1.了解OC语言的起源

OC 为C语言添加了面向对象特性,是其超集
基于C语言,runtime组件,引用计数,C语言的内存模型, 定义不含* 可能使用栈空间,保存的不是OC对象,如结构体使用(开发中较为实用,config适用),较objcet性能好

2.在类的头文件中尽量少引用其他头文件

.h 使用 @class EOCEmployer;
前行声明(forward declaring)该类,若.m要调用该类方法,在.m中引用
#import "EOCEmployer.h"
将引入头文件的时机尽量延后,只有在却有需要时引入
两个类在各自的头文件中引入对方的头文件,会导致两个类又一个无法被正确便衣。 代理无法前向声明,最好将声明移到 "class -continutaion"里 ,或者协议单独放一个.h文件在引入(比如 ChatBarProtocol.h)

3.多用字面量语法,少用与之等价的方法

  • 字符串字面量
    NSString *str = @"hello world";
  • 字面数值
    NSNu *num = @1";
  • 字面量数组
    NSArray *arr = @[@"1",@"2"];
    NSString *str = arr[0]

字面量为空时会抛出异常,字面量语法只是一种"语法糖"

  • 字面数值
    NSDictionary *dic = @{@"key",@4};

4.多用类型常量,少用#define预处理指令

static const CGFloat cellHeight = 32.0f;
代替
#define cellHeight = 32.0f
注意如果只是内部使用,写在.m里,在前面加字母k,若其他地方也要使用,以类明为前缀(19条)

公开某个常量,常见于通知字符串 ,存放在全局符号表(global symbol table)
.h 声明 extern NSString *const LoginSuccess;
.m实现 NSString *const LoginSuccess = @"kLoginSuccess";

补充说明:

  • static 修饰局部变量后,该变量只在初次运行时进行初始化工作,且只进行一次
  • extern 用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”
  • const 强制定义,不可更改

5.用枚举表示状态,选项,状态码

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

1 << 0 “按位或操作符” 位运算(二进制)相加,由于二进制相加之后唯一,就确保了枚举的唯一性。可以用uint种方式来初始化一个位运算枚举。

 typedef NS_ENUM(uint, CellType)
{
    kHomeCellNews,
    kHomeCellPaper,
    kHomeCellImg,
    kHomeCellVideo,
};

若使用枚举定义状态机,在switch中最好不要加default分支,确保switch正确处理所有样式(这个要注意)
使用NS_ENUM 和NS_OPTIONS时,指明底层数据类型
在开发中尽量要和iOS 系统库里代码保持一致,枚举,结构体,单例,内联等等。

第二章对象,消息,运行时

6.理解“熟悉”这一概念

  • @protrerty 自动生成get,get方法
  • 点语法与直接调用get,set方法没有丝毫差别!!
  • 假如只实现了get set中的一个,另一个还是回由系统帮助生成, 若使用@dynamic 告知系统,手动实现setget
  • iOS 6 之后 LLVM 编译器引入property autosynthesis,即属性自动合成。换句话说,就是编译器会为每个 @property 添加 @synthesize ,如以下形式:
    @synthesize propertyName = _propertyName;

属性特质:
-nonatomic 不使用同步锁,读写权限,
读写权限:
readwrite 拥有get,set方法
weadonly 只拥有get方法,当属性@synthesize实现时,编辑器会为其合成获取方法(在第27条中,属性.h声明为只读, 在实现中将其从新定义为读写属性)
assign 简单赋值
strong 持有关系,set新值时,会保留新值,释放旧值,将新值设置上去
weak 非持有关系,set时,不保留新值也不保留旧值,属性对象销毁时,属性清空
unsafe_unretained 类似assign,非持有,属性对象销毁时,属性不会清空开发中和weak的区别不是太懂,网上找了一个例子 (MyViewController 拥有 MyView, MyView 需要调用 MyViewController 的接口。MyView 中就可以存储 __unsafe_unretained MyViewController* _viewController)
__unsafe_unretained UITableView *tableView = self.tableView;
copy 设置新值不保留新值,而是将其拷贝一份,保护其封装性,比如外部赋值了一个mutableString,确保不会无意间被变动。

7.在对象内部尽量直接访问实例变量

直接访问变量跳过get方法,假如ARC下访问copy属性,不会拷贝新属性,保留新值,释放旧值,不会触发"键值观察"通知,这点要注意
合理方案,写入变量时,set方法,读取时,直接访问实例变量

self.shareName = @"hello world";
NSString *str = _shareName;

注意:

  1. 懒加载必需调用get方法,不然属性永远不会初始化
  2. 初始化时应该直接赋值属性变量,子类可能会覆盖set方法

8.理解“对象等同性”这一概念

相关文章

网友评论

      本文标题:Effective Objective-C 2.0 编写高质量i

      本文链接:https://www.haomeiwen.com/subject/wouspqtx.html