感觉自己最近提升很慢了。然后去找了一些面试题看看。发现自己自大了。在实际开发中,让我解决bug、编写功能,我有自信可以完成。但是对项目更深层的思考,我却没有。为了能进到自己的目标BAT。也为了让自己更进一步发展。目前是计划是先看《Effective Objective-C 2.0》、《Objective-C高级编程:iOS与OS X多线程和内存管理》2本书,并将AFN、YYCache、SDWebImage等开源源码再认真看一遍,并写下自己的读后总结。

  《Effective Objective-C 2.0》总结出编写高质量iOS与OX X代码的52个技巧。看完后,觉得还是有很多之前没有注意到的地方,认识到自己的不足之处。这里总结就不一一列举所有的技巧,重点是介绍我觉得比较实用的点,有些比较理论的知识比如对象所占的内存总是分配在“堆空间”就不在这里介绍了,有兴趣的同学,可以去看看全本书,值得推荐。

  

  1.在类的头文件中尽量少引用其他头文件,因为过多引入头文件会增加编译时间。在.h中最好使用向前声明"@class"方式。这样一方面可以降低类之间的耦合,另一方面可以防止2个类的互相引用。

  2.尽量使用字面量语法来创建字符串、数值、数组、字典。这种方式看起来更加简明扼要,而且创建数组、字典时可以保证不会出现nil。

  1. //字面量语法:
  2. NSNumber *intNumber = @;
  3. NSNumber *floatNumber = @1.2f;
  4. int x = ;
  5. float y = 2.32f;
  6. NSArray *arr = @[@"one",@"two",@"three"];
  7. //其他语法创建就是比如的alloc等。。

  3.多用类型常量(static const),少用#define预处理指令。不要用预处理指令定义常量。这样定义出来的常量不含类型信息,编译器只是会在编译前据此执行查找与替换操作。即使有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中的常量值不一样。另外使用类型常量时也要注意命名,是否要加前缀之类的。

  4.使用枚举来表示状态机的状态、传递给方法的选项以及状态码等值。与创建结构体相比,创建对象还需要额外开销,例如分配及释放堆内存等。在处理枚举类型的switch语句中不要实现default分支。这样的话,加入新枚举之后,编译器就会指示开发者:switch语句并处理所有枚举。

  5.iOS开发中几乎所有属性都声明为nonatomic,这是因为iOS中使用同步锁开销很大,这会带来性能问题,但是这不能保证“线程安全”,所以在特定的时候要学会修改为atomic,但是大部分时候还是用nonatomic。

  6.在对象内部尽量直接访问实例变量。最直白的区别是在对象内使用:self.name是属性访问。_name是直接访问。推荐_name。   

    两种写法的区别
    *由于不经过OC的方法派发步骤,所以直接访问实例变量的速度比较快。
    *直接访问实例变量时,不会调用其“设置”方法,这就绕过了为相关属性所定义的“内存管理语义”。比方说,如果在ARC下直接访问一个声明为copy的属性,那么并不会拷贝该属性,只会保留新值并释放旧值。
    *如果直接访问实例变量,那么不会触发“键值观测KVO”通知。这样做是否会产生问题,还取决于具体的对象行为。
    *通过属性来访问有助于排查与之相关的错误,因为可以给“获取方法”、“设置方法”中新增“断点”,监控该属性的调用者及访问时机。
    **在写入实例变量时,通过其“设置方法”来做,而在读取实例变量时,则直接访问之。
  7.判断对象是否相同时,除了要重写isEqual方法之外还要重写hash方法,保证hash密码也要相同。
  8.判断类对象时,“isMemberOfClass”能够判断出对象是否为某个特定类的实例。而“isKindOfClass”能够判断出对象是否为某类或其派生类的实例。这里尽量使用“isKindOfClass”,因为某些类可能实现了消息转发功能。
  9.编写自己的类库时,最好加上自己的前缀。公司的项目则看项目组要求。
  10.实现description方法,可以更方便的打印出对象的信息。
  11.尽量使用不可变对象。
  12.使用清晰而协调的命名方式,方法名要言简意赅,从左到右读起来要像个日常用语中的句子。
  13.给私有方法的名称加上前缀,这样可以很容易 的将其公共方法区分开。
  14.OC的错误应该由NSError对象来输出,如果不是重大错误,会导致程序崩溃的不要使用抛出异常。这和其他语言有很多的不同,因为在抛出异常的时候有可能会导致内存泄露,所以不支持过多使用,只有在重大错误才用。
  15.通过委托与数据源协议进行对象间通信。使用委托协议更有利于代码的解耦。
  16.使用分类机制把类的实现划分成易于管理的小块。
  17.勿在分类中声明属性。
  18.在dealloc方法里,应该做的事情是释放指向其他对象的引用,并取消原来订阅的“键值KVO”或NSNotificationCenter等通知。不要做其他事情。
  19.以弱引用避免保留环,即避免循环引用。
  20.以“自动释放池块”降低内存峰值。在for循环中使用更多,一遍创建信息,使用后释放。即在for循环中一遍创建结束后就可以释放,这样内存峰值就不会太高。
  21.如果块(block)所捕获的对象直接或间接的保留了块本身,那么就得当心保留环问题,不是每一个self都会循环引用,但是在使用时还需要多加注意。
  22.多用派发队列(GCD),少用同步锁。将同步和异步派发结合起来,可用实现与普通加锁机制一样的同步行为,而这么做却不会阻塞执行异步派发的线程。使用同步队列及栅栏块,可以令同步行为更加高效。
  23.GCD更适合大体的多线程操作,如果要更细致的操作多线程则使用NSOperationQueue操作队列,如需要取消线程操作、指定操作的优先级、监听键值变化、指定操作间的依赖关系等。
  24.通过Dispatch Group机制,根据系统资源状况来执行任务。
  25.使用dispatch_once来执行只需运行一次的线程安全代码。(编写单例对象时,推荐使用)。
  26.遍历时多用块枚举,少用for循环。在数组中可能不明显,但是在字典、set这些无序的信息时,使用for循环就需要性能额外的开销了。而快速遍历又不能有更全的对象信息,所以最推荐块枚举遍历。
  27.缓存信息时,尽量使用NSCache,而非选择NSDictionary。因为系统发出“低内存”的时候会自动删减缓存,而不需要自己手动去删减。而且NSCache是线程安全的,NSDictionary是绝对不具备此优势的。还能可以给NSCache对象设置上限。如果缓存使用得当,那么应用程序的相应速度就能提高。只有那种“重新计算起来很费事的”数据,才值得放入缓存,比如那些需要从网络获取或从磁盘读取的数据。
  28.在使用initialize与load这2个初始方法的时候要尽可能精简。在里面设置一些状态,使本类能够正常运行就可以了,不要执行那种耗时太久或需要加锁的任务。
  29.使用NSTimer主要循环引用和用完释放的问题。

《Effective Objective-C 2.0》 读后总结的更多相关文章

  1. 我的第一本docker书-阅读笔记

    花了三四天看完了我的第一本docker书,话说书写的还是挺简单易懂的.与传统的VM,VirtualBox,或者与那种内核虚拟的xen,kvm相比,docker作为一种容器的虚拟方式,以启动进程的方式来 ...

  2. 《第一本docker书》—— 读后总结

    关于docker 这本书其实并没有读完,只不过最近工作比较繁忙,也无心再看这些用不到的书.以后要是工作需要,再仔细学习吧. 这次的阅读算是达到目的了,对docker有了一定的了解.它的作用.意义以及大 ...

  3. 第一本Docker书读书笔记

    日常使用命令 1.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有container的话再加一个指令: ...

  4. 《第一本Docker书》

    Docker简介 Docker依赖写时复制(copy-on-write),使修改应用程序非常迅速. Docker推荐单个容器只运行一个应用或进程,鼓励面向服务的架构和微服务架构. Docker的核心组 ...

  5. 第一本docker书 学习笔记(二)

    #安装docker的先决条件 运行64位CPU构架的计算机(docker目前不支持32位的cpu) 运行LUFSinux3.8或者更高版本内核 内核必须支持一种合适的存储驱动,例如: device M ...

  6. 《第一本Docker书》学习笔记——第3章 Docker入门

    3.1 确保Docker已经就绪 查看docker是否正常工作: sudo docker info 3.2 运行我们的第一个容器 现在,让我们尝试启动第一个Docker容器.我们可以使用docker ...

  7. 《第一本docker书》- 第一章笔记

    环境: Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic i686) 第一章: 1 Docker客户端和服务器 2 Docker镜像 添加一个文件,执行一 ...

  8. 《第一本docker书》第4章 使用docker镜像和仓库 读书笔记

    docker最底端是一个引导文件系统,即bootfs. 第二层是root文件系统rootfs,位于引导文件系统之上. 在传统的Linux引导过程中,root文件系统会最先以只读的方式加载,当引导结束并 ...

  9. 第一本docker书,,持续更新中

    1.查看应用是否在docker中部署成功 需要确认curl已安装 whereis curl sudo apt-get -y install curl curl localhost:8081   如果成 ...

  10. 第一本docker书 学习笔记(一)

    Docker的核心组件: Docker客户端和服务端 Docker镜像 Registry Docker容器 # Docker客户端和服务端 docker 是一个 C/S架构程序.客户端只需要向dock ...

随机推荐

  1. iOS开发之圆角指定

    如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可(项目需要使用QuartzCore框架).而若要指定某几个角(小于4)为圆角而别的不变时 ...

  2. 转载:ECMAScript 6简介

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发 ...

  3. FZU 2098 刻苦的小芳

    这个问题转化一下就是求长度为2*n的正确括号匹配串,两个匹配的括号之间的距离不超过2*k的有几种. 假设左括号为1,右括号为-1,dp[i][j]表示长度为i的括号匹配串,前缀和为j的有几种.dp[2 ...

  4. 微信小程序之----生命周期

    在app.js的app()中注册程序 在页面.js中的Page({})中注册页面. 执行效果:

  5. .net面试题【持续更新.....】

    1.C#中readonly和const的区别? 2.C#中的排序继承自哪个接口?Icompare 3.阐述单点登录的实现原理? 4.C#中property和Attribute的区别? 5.Datase ...

  6. js动画学习笔记

    <html> <head> <meta charest="utf-8"> <title>test</title> < ...

  7. Linux文件编辑之sed命令

    文件编辑之sed命令 sed是一种流编辑器,它是文本处理中非常重要的工具,能够完美配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时缓冲区中,称为模式空间 (pattern space ...

  8. windowsxp系统下SVN添加新用户

    以我部署的文件为例: 我在f盘下新建一个zzz文件夹将其部署为svn共享工程后,新来员工需要添加svn账号以获取工程. 总共三步begin: 1.进入工程文件夹ZZZ在里面有一个conf文件夹如图: ...

  9. 转自他人——————TLE之前,没有一个节点叫失败!!!

    我想我十八年来记忆最深刻的夜晚,大概便是在吉林大学燥热的宿舍里,穿着橘黄色的短袖,努力咽下大口大口的雪碧.那天晚上我仰躺在吉大热得几乎不能入眠的床板上,一动不动,看夏夜里打不尽的蚊子在惨白的天花板下飞 ...

  10. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...