美文网首页
熟悉Objective-C

熟悉Objective-C

作者: 晨阳Xia | 来源:发表于2020-11-05 15:11 被阅读0次

[toc]

熟悉Objective-C

第 1 条 了解Objective-C语言的起源

虚方法表

是编程语言为实现“动态派发”或”远行时方法绑定“而采用的一种机制。

内存分配

NSString *someString = @"The string";
NSString *anotherString = someString;
此内存布局:someString,anotherString分配在栈上,@"The string"(NSString data)分配在堆中
分配在堆中的内存必须直接管理,而分配在栈上用于保存变量的内存则会在栈帧弹出时自动管理

要点:

  • Objective-C为C语言添加了面向对象特性,是其超集。Objective-C使用动态绑定的消息机构,也就是说,在运行时才会检查对象的类型。接受一条消息之后,究竟应执行何种代码,由运行期环境而非编译器决定。

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

前置引用解决了两个问题

  1. 编译更快
  2. 避免了类的循环引用

引用头文件的时候需要考虑两个问题

  1. 自己是否有必要这样做,是否可以采用前置引用的方式
  2. 若因为要实现属性、实例变量或者要遵循协议而必须引入头文件,则应尽量将其移至“class-continuation”总(参考 第27条)

要点

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

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

字面数值

方便简洁

字面量数组

  1. 方便简洁
  2. 遇到nil的问题会直接报一场没如果使用[NSArray arrayWithObjects:object,object2,object3],如果object2为nil,则数组中只会包含一个元素。(原因在于“arrayWithObjects”方法会依次处理各个参数,知道发现nil为止,由于object2是nil,所以该方法会提前结束)

字面量字典

  1. 方便简洁
  2. 可对可变数组或字典直接赋值

局限性

  1. 除了字符串以外,所创建出来的对象必须属于Foundation框架才行
  2. 如果自定义了这些类的子类,则无法用字面量语法创建其对象。

要点

  • 应该使用字面量语法来创建字符串、数值、数组、字典。与创建此类对象的常规方法相比,这么做更加简明扼要。
  • 应该通过取下标操作来访问数组下标或字典中的键所对应的元素。
  • 用字面量创建数组或字典时,若值中有nil,则会抛出异常。因此,务必确保值里不含nil

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

编译单元

编译器没收到一个编译单元,就会输出一份“目标文件”,“编译单元”一词通常指每个累的实现文件(以.m为后缀名)

定义常量应该注意

勿使用与处理指令定义常量,而应借助编译器来确保常量正确,比方说可以在实现文件中用static const来声明常量,也可以声明一些全局变量。

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

字节

一个字节含8个二进制位,所以最多能表示可取256种枚举

要点

  • 应该用枚举表示状态机的状态、传递给方法的选项以及状态码等值,给这些值起个易懂的名字。
  • 如果把传递给某个方法的选项表示为枚举类型,而多个选项有课同时使用,那么就将个选项值定义为2的幂,以便通过按位或操作将其组合起来。
  • 用NS_ENUM与NS_OPTIONS宏来定义枚举类型,并指明器底层数据类型。这样做可以确保枚举是用开发者所选的底层数据类型实现出来的,而不会采用编译器所选的类型。
  • 在处理枚举类型的switch语句中不要实现default分支。这样的话,加入新枚举之后,编译器就会提示开发者:switch语句并未处理所有枚举。

import,#include,@class 的区别

  1. “#import”与“#include” “#import”不会引起交叉编译的问题。因为在Objective-C中会存在C/C++和Object-C混编的问题,如果用“#include”引入头文件,会导致交叉编译。
  2. “#import”<>与“#import"" 在实际运用中都是某个框架里的.#import <Three20/Three20.h><>通常指向的是一个目录#import ""则直接是文件名。 Objective-C 中 #import 和 #include 的区别
  3. 预编译指令 Objective-C:#import C,C++:#include #import由gcc编译器支持 在 Objective-C 中,#import 被当成 #include 指令的改良版本来使用。除此之外,#import 确定一个文件只能被导入一次,这使你在递归包含中不会出现问题。 使用哪一个还是由你来决定。一般来说,在导入 Objective-C 头文件的时候使用 #import,包含 C 头文件时使用 #include。比如: #import #include #include #import比起#include的好处就是不会引起交叉编译
  4. 二、@class是用来做类引用的 @class就是告诉编译器有这么一个类,至于类的定义是啥不知道 @class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import 举个例子说明: 在ClassA.h中 #import ClassB.h 相当于#include整个.h头文件。如果有很多.m文件#import ClassA.h,那么编译的时候这些文件也会#import ClassB.h增加了没必要的#import,浪费编译时间。在大型软件中,减少.h文件中的include是非常重要的。 如果 只是@class ClassB 那就没有include ClassB.h。仅需要在需要用到ClassB的ClassA.m文件中 #import ClassB.h 那么什么时候可以用@class呢? 如果ClassA.h中仅需要声明一个ClassB的指针,那么就可以在ClassA.h中声明 @ClassB ... ClassB *pointer;

static, const, extern 的区别

参考链接

extern

  1. 声明一个变量,不能定义变量
  2. 注意:extern修饰的变量不能初始化
  3. 使用场景,一般用于声明全局变量

在iOS开发中请尽量多使用const、enum来代替宏定义(#define),随着项目工程的逐渐增大,过多的宏定义还可能影响项目的编译速度.

正规的定义全局常量的方式:

.h文件中
extern NSString *const name;

.m文件中
static NSString *const name = @"xsy";

如有建议,欢迎留言。谢谢

相关文章

网友评论

      本文标题:熟悉Objective-C

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