菜鸟读《Effective objective-c 2.0》 极简读书笔记(持续更新)

此读书笔记是本人每日坐地铁上看书 的总结,本人是一个渣渣,而且刚开始写博客,所以总结的肯定有不对的地方,望各位批评指点,其中不讲那些原理了啥的比较虚的,直接上的都是我觉得平时工作开发中能用的上的干活,给有需要的亲们分享

第1条:了解objective-c 语言的起源

说白了就是老生常谈oc 身为运行时语言较C++ Java的一些好处,动态绑定技术,运行时才会检查对象类型,身为一个渣渣来说,这些只是了解,等自己高大上了,才能更好的理解人家这牛逼的地方

第2条:在类的头文件中禁令少引用其他头文件

简单的说就是头文件在需要的时候在引入,尤其是是在.h文件中尽量不要引入其他头文件,这样可以有效的避免循环引用,增加编译时间,在.h文件中尽量多用@class ClassName也就是所谓的向前声明,尽量把需要遵守的协议添加到分类中,如果不行就单独放一个头文件,总的来说就是尽量把引入的这件事分开搞,如果一个文件引入了好多文件,他在被引用的话,一是编译慢,二是容易出循环引用。

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

字面量语法说白了就是一层语法糖,前代牛逼大神封装好了,让我们方便调用在创建,使用字符串,数值,数组,字典的时候最好多用,原因捞干很简单,人家大神封装的时候已经内部做好了好多判断,可以抛出很多异常,可以让大家撸代码的时候省时省力。
例如:

//        字面量创建的变量
        NSString *someString = @"读书笔记";
//        普通创建
        NSString * someString1 = [[NSString alloc]initWithFormat:@"读书笔记"];
        
        NSNumber * someNumber = @1;
        NSNumber * someNumber1 = [NSNumber numberWithInt:1];
        
        NSArray * someArray = @[@"a",@"b",@"c",@"d"];
        NSArray * someArray1 = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d", nil];
        
        NSDictionary * somedict=@{@"first":@"a",@"Two":@"b"};
        NSDictionary * somedict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"first",@"a",@"Two",@"b", nil];

在使用变量的时候也是尽量使用[]语法,方便安全,需要注意的是使用[]语法在使用到其中有nil的时候,就会抛异常,方便排除,还有普通创建的时候如果数组,字典中有nil,则直接当成已达到尾端,后面的就不会再操作,而字面量中,会把nil也当成元素填入

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

我平时也是经常使用#define指令,看了才知道,要少用,原因两个,一个使用预处理指令不会只是简单的替换,不会检查变量类型;二是如果你设置了个全局的预处理变量,如果某人在其他文件里又设置了个一样的,那样你也不知道,到时候就GG了,所以所以后多用已下方法搞全局变量

在此类中的全局全局声明
static const int ALLCLASSINT = 5;

在整个工程中的全局声明,记住要在.h文件中搞,具体的看看C语言的基础就知道了
 extern NSString * const ALLSTRING = @"全局变量";

第5条:用枚举表示状态、选项、状态码

这个没啥说的所有语言通用,基础中的基础

第6条:理解“属性”这一概念

原书说了一大堆,说的都是概念,有用的就是iOS开发中应该用@property创建的变量会对其进行封装设置get 、set等,声明的时候要声明nonatomic(不加锁),而不要声明atomic(加原子锁),其他的属性根据需要加,个人觉得即使不多加,也不要瞎加,如果加错了反而会照成错误

第7条:在对象内部尽量直接访问实例变量

在对象内部读取数据时,应该直接通过实例变量来读,而写入数据时,则应通过属性来写。
简单的说读取变量的时候直接用 _abc 方法,设置变量的时候适合用 self.abc 来设置 在懒加载是应该用_abc 不过想要出发懒加载时应该用self属性来读取数据

第8条:理解“对象等同性”这一概念

oc中==操作符比较的是两个指针本身,而非所指向的内容,所以oc中提供了很多等同性API供我们使用,class 中有 isEqual,NSString中有isEqutalToString;NSArray中有isEqualToArray;NSDictionary中有isEqualToDictionary。在判断时候最好用等同性函数更加准确,还有就是尽量不要修改意见存在数组或者集合中的指针,这样比较容易让编译器做出不符合你预期的动作,逐条检测时更加要多多细心

第9条:以“类族模式”隐藏实现细节

文中讲述了用工厂方法创建的对象的好处,

中间后续再看

第15条:用前缀避免命名空间冲突

因为oc中并没有C++中的命名空间,以及Java中的jar概念,所以比较容易出现命名冲突这个问题,这个时候解决的办法是用不同的前缀来避免命名冲突,这样做的好处不言而喻有效,而且在堆栈信息中查看问题的时候还比较好定位问题

第16条:提供“全能初始化方法”

每个类都应该一个全能初始化方法,在最终创建的时候都调用此方法创建类,如果子类里的方法和超类里的方法不同的话,应该覆盖超类的方法,如果方法不适用,那么子类应该覆盖原方法,并在中间抛异常。

第17条:实现description方法

自己封装的类如果从外部直接用nslog打印的话,只能看到默认信息也就是指针值,这个对于调试并没有什么乱用,所以作者推荐在类中实现description方法,这样在外部用nslog打印的时候就可以显示出你所需的信息,如果想只在模拟器中用控制台打印信息的话可以调用debugDescription函数。

第18条:尽量使用不可变对象

在很多某些情况下,我们接受到了数据保存到对象中之后就不需要修改原数据了,所以作者推荐我们尽量的创建不可变的对象属性设置为readonly;如果需要在对象内部进行修改,但是不需要外部修改就可以将readonly属性变为readwrite属性,这样编译器就可以很好的起到限定的工作,还有不要把可变的数组,字典,集合作为公开属性,要设置相关的方法操作这些属性。

第19条:使用清晰而协调的命名方式

类,方法以及变量的命名是objective-C编程的重要环节而且oc中的命名规则有事与众不同,我们起名时要遵守命名规范,从左向右读起来要像个日常用语的句子才好,方法名里不要使用缩略后的类型名称,起名的第一要务就是确保你自己的代码或所要集成的框架相符。

第20条:为私有方法名加前缀

给私有名称上加上前缀可以和公共方法区分开,不过不要用一个下划线作为前缀,因为这个需要预留给苹果公司。

第21条:理解objective-c错误类型

oc抛异常比较麻烦,所以不能像Java那样随便抛异常,只有在导致崩溃的时候才应该使用异常,一般都是用代理来处理错误,放到NSError里,由返给调用者

第22条:理解NSCopying协议

如果想对自己写的对象具有copy功能应该遵守NSCopying协议,一般默认执行的都是浅拷贝,如果想执行深拷贝需要单独封装相应的方法

第23条:通过委托与数据源协议进行对象间通信

委托所说的就是代理,本节讲述的就是通过代理进行通信,不过个人认为代理实现起来还是比较复杂,如果可以的话还是多用block这个更简单好用,而且不会把代码分散的到处都是,不方便查看

第24条:将类的实现代码分散到便于管理的数个分类之中

如果一个类功能比较多经常容易填满各种方法非常不善于维护,可以用oc的分类机制来讲代码按逻辑划入不同的区域,这对开发与调试都有好处,还有可以把不想暴露出去的私有方法放到名字Private的分类中,可以隐藏实现细节,让使用者无法调用。

第25条:总是为第三方类的分类名称加前缀

因为oc为在运行期系统才会加载,所以你自己写的分类名称如果和系统自带的方法或者第三方的分类方法重名的话就会进行覆盖,这样就会造成很大的不便,所以为你自己的分类名称和方法添加自己的前缀可以避免这种问题。

第26条:勿在分类中声明属性

不要把数据声明在分类中应该定义在主接口中,如果有需要可以定义存存储方法。

第27条:使用分类隐藏实现细节

中间略过

第31条:在dealloc方法中只释放引用并解除监听

** -(void)dealloc**函数是在类真正被销毁的时候自动调用,开发者不可以主动调用此类,在ARC下此类无需调用super方法。所以在此类适合调用解除监听方法,例如:“键值观测(KVO)” 活NSNotificationCenter等通知,不要做其他事情。原因销毁方法不可控,如果在此方法中调用进行释放文件资源、系统资源或者开子线程等待回调等,就容易出现问题,因为线程可能未回调就被kill 或者主线程本身就kill,时间太长的话可能未执行就被杀死了。如果要释放这种较大资源的释放,最好自己封装专门的释放函数,预留两份清理代码。

第32条:编写“异常安全代码”时留意内存管理问题

当抛异常时如果在异常时会存在new了新的类 但是没等到release的时候就抛异常了,这时候就无法释放对象了,所以应该讲应该添加@finally{}方法,在此方法内对class进行释放。不过上述说的是MRC的情况,如果在ARC的情况下,不会在@finally{}方法中自动调用release方法,因为这样会创建大量样板代码从而影响性能。如果想要生成这种附加码需要打开编译器的-fobjc-arc-exceptions标志但是会降低效率,需要谨记。

第33条:以弱引用避免保留环

如果两个及其以上对象之间进行强引用就会形成保留环。保留环的危害就是相互引用会导致互不释放,最后会导致泄漏。避免方法就是将某些引用设置成weak或者unsafe_unretained。
两者的区别是前者释放后指向为nil,后者还指向之前的对象。weak引用可以自动清空,也可以不自动清空。自动清空是随着ARC而引入的新特性,由运行期系统来实现。在具备自动清空功能的弱引用上,可以随意读取数据,因为这种引用不会指向已经回收过的对象。

第34条:已“自动释放池块”降低内存峰值

如果某个代码块初始化时创建出一些不需要持续存在的临时对象时应该提早回收,增加一个自动释放池可以解决问题,在循环中自动释放的对象就会放在这个池中,而不是线程的主池里面。采用@autoreleasepool{}新式写法能够更轻便的创建出自动释放池,讲此工作交给操作系统省时省力。

    原文作者:继续向前冲
    原文地址: https://www.jianshu.com/p/58de3f27ce78
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞