《Effective Objective-C 2.0》读书笔记(一)

本读书笔记仅为本人阅读此书的一些总结和联想,并非图书精讲。

第一章

第一条 了解Object-C 语言的起源

Object-C是C语言的超集,是一门面向对象的语言。该语言使用“消息结构(messaging structure)”而非“函数调用(function calling)”。关键区别在于:使用消息结构的语言,其运行时所应执行的代码由运行环境来决定;而使用函数调用的语言,则由编译器决定。
关于消息结构的动态语言特性,在学习runtime相关知识后会有较为深刻的理解,但是与函数调用的区别还是应掌握门对应的语言才能更加深刻的对其特性有所理解。
本章中多次提出 开发者应理解C语言的核心概念有助于写好Objective-C程序。尤其要掌握内存模型与指针。
Object-C有OC语言封装的API比如NSRunLoop也有c语言的API CFRunLoop。在一些功能性的框架中也有对c语言的使用比如#import <AudioToolbox/AudioToolbox.h>对h.264视频进行硬解码编码等。

    int a = 10;
    int * p = NULL;
    p = &a;
    NSLog(@"%d - %lu",*p,sizeof(*p));
    NSLog(@"%d",*p);
   输出10 - 4

p为int *型的指针 ,这个指针包含了两个要素:1、一个是指针指向的内存首地址 也就是在计算机内存中的起始位置。另一个是内存中存放数据的类型。本例子中a为int型在内存中占4个字节。这样知道位置知道长度就可以准确的找到数据了。

第2条 在类的头文件中尽量少引入其他的头文件

在OC中对文件的引用有如下几种
@import Photos;                                 下面单独讲解
@class EOCModel;                              向前声明 
#import <CoreVideo/CoreVideo.h>   引用系统文件
#import"EOCModel.h"                        引用自定义文件

#include< >引用的是编译器的类库路径里面的头文件。
#include“ ”引用的是你程序目录的[相对路径]

首先讲解下@import
ios-@import和#import
@import是个什么,和#import啥区别
通过以上两篇文章的理解可以简单总结为:所有的#import和#include指令都被映射为自动使用@import。 @import不必单独使用,直接用#import和¥include就行和 在链接二中有说明。@import也是防止重复引用提高编译效率的一种方法。

LLVM9中的modular默认状态.png

import 和include 的区别 使用include会引起文件的重复引用和文件引用的循环嵌套,import可以解决重复的问题,但是文件的循环引用问题无法的到解决。比如在第二条中EOCPerson和EOCEmployer的引用问题。如果使用@class即可解决。 代码和发生的问题如下

@class 在编译某个文件时不需要知道引入类的全部实现,只需要知道一个类型就好,可是使用@class 代替#import。

#import <Foundation/Foundation.h>
@class  EOCEmployer;
//#import "EOCEmployer.h"

@interface EOCPerson : NSObject

@property (nonatomic, copy) NSString * firstName;
@property (nonatomic, copy) NSString * lastName;
@property (nonatomic, strong) EOCEmployer * employer;

@end
#import <Foundation/Foundation.h>
#import "EOCEmployer.h"
#import "EOCPerson.h"

@interface EOCEmployer : NSObject

- (void)addEmployee:(EOCPerson *)person;
@end
头文件嵌套问题.png

除非有必要,否则不要引入头文件。一般来说在某个类的头文件中使用向前声明来提及别的类,并在实现文件中引入那些类的头文件。这样做可以尽量降低类之间的耦合。
有时无法使用向前声明,比如要声明某个类遵循一项协议。这种情况下,尽量把“该类循序某协议”的声明移动至“class - continuation分类”中。如果不行的话,就把协议单独放在一个头文件中,然后将其引入。

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

  • 应该使用字面量语法来创建字符串、数值、数组、字典。与创建此对象的常规方法相比,这么做更加简明扼要。
  • 因该通过取下标操作来访问数组下标或字典中的键所对应的元素。
  • 用字面量语法创建数组或字典时,若值中有nil,则会抛除异常。因此,务必确保值里不含nil; (常见的处理方法使用runtime来防治这类的crash发生 git中也有很多开源项目)
    NSString * cat = @"cat";
    NSString * dog = nil;
    NSString * pig = @"pig";
    
    NSArray * arrayA = [NSArray arrayWithObjects:cat,dog,pig, nil];
    NSLog(@"arrayA count:%d",arrayA.count);
    NSArray * arrayB = @[cat,dog,pig];//字面量
    //使用字面量方法初始化arrayB时会抛出异常,arrayA的初始化方法会一次处理各个参数,直到发现nil为止。dog是nil,所以会提前结束。

第四条 多用类型常量,少用#define预处理指令

有些c基础的 应该知道#define 就是一个替换作用 比如定义了一个宽度 #define kMyBtnWidth 25.0 在程序中使用 self.myBtn.width = kMyBtnWidth; 如果 #define kMyBtnWidth 25.0; 这样添加宏定义的话self.myBtn.width = kMyBtnWidth 我们就不用在结尾添加;了。
这里插一个需要注意的地方 定义需要考虑使用场景。比如第一个一个加法 #define kLWAdd 3+5 在使用使用中我们是这样的

  #define  kLWAdd  3+5
  int result =    kLWAdd + 5; //打印 a ==13
   //换乘法
  int result2 = kLWAdd * 2;//打印结果 a==13  为啥不是16呢 8*2=16啊。这就使替换的问题 上面相当于 int result2 = 3+5 * 2;
  //这时我们应该这样定义   #define  kLWAdd  (3+5) 
  int result2 = kLWAdd * 2;//打印结果 a==16

因为不是常量因此可能会被更改 并且数据的类型不明确。比较好的做法如下
在.h文件中
extern NSString * const kLWRequestURL;
在.m文件中
static NSString * const kLWRequestURL = @"http//aaaaa";

static 关键字会让相关代码作用于本文件中 extern在.h中把声明暴漏给所有文件使用。NSString * 指向一个常量 是指针常量。

同时还有另外一个好处,就是不使用#define 时可以减少编译时间。XCode在运行程序的使用也是要进行编译 连接的。比如在修改的项目的运行借口 宏定义。从测试接口转换为线上接口,是不是感觉command + r的时间变长了呢。

第5条 用美剧表示状态、选项、状态码、

1.提到枚举首先想到的就是 NS_ENUM 系统默认第一个枚举为0 如果我们修改第一个枚举为2 那么接下来的枚举回依次增加。
2.还有一种枚举为NS_OPTIONS 是位移枚举,枚举的数据不在时NSUInteeger 我们可以在后面设置选项值的二进制大小。这种枚举值的定义为2的幂。好处就是可以通过按位或同时设置多个状态而不会出现数据混乱的问题。具体例子书中很明确不在赘述。使用中的例子,比如SDWebImage 的方法如下

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

推荐阅读更多精彩内容

  • 听一位妈妈抱怨:儿子原本很听话,但读初二以后,突然像变了一个人似的,父母跟他说什么话,他都要顶撞回来,有时干脆不搭...
    普渡pd阅读 391评论 0 3
  • “曲奇饼”在所有孩子中学习成绩是最好的,是班级里的学霸。成绩最差的是乐乐,语文、数学、英语三门课程都处...
    杨芽阅读 106评论 0 0
  • 1、OSI国际标准化IOS参考模型2、OSI七层模型的划分应用层表示层会话层传输层网络层数据链路层物理层 3、各层...
    赵庆_be43阅读 348评论 0 0