1、了解Objective-C语言的起源

Objective- C与C++、Java面向对象语言类似,不过很多方面有所差别。语法上该语言使用消息结构”而非“函数调用”。Objective-C语言由Smalltalk演化而来,后者是消息型语言鼻祖。
消息与函数调用之间区别:

//Messaging(Objevtive-C)
Object *obj = [Object new];
[obj performWith:parameter1 and:parameter2];

//Function calling(C++)
Object *obj = new Object;
obj->perform(parameter1, parameter2);

关键区别:
使用消息结构的语言,其运行所应执行的代码由运行环境来决定;而使用函数调用的语言,则由编译器决定。对于函数结构,如果范例代码的调用函数多态的,那么就在运行时按照虚方法表来查出来到底执行哪个函数,而采用消息结构的语言,不管是否多态总是在运行时才会去查找所要执行的方法。实际上,编译器甚至不关心接收对象是何种类型。接受消息的对象问题也要在运行处理,其过程叫做“动态绑定”。

运行组件
Objective-C的重要工作都由“运行期组件”(runtime component)而非编译器完成。使用Objective-C的面向对象特性所需的全部数据结构函数都在运行期组件里面。举例来说,运行期组件中含有全部内存管理方法。运行期组件本质就是一种与开发者所编代码相链接的“动态库”(dynamic library),其代码能把开发者编写的所有程序粘合起来。这样的话,只需更新运行期组件,即可提升应用程序性能。而那种许多工作都在“编译期”(compile time完成的语言,若想获得类似的性能提升,则要重新编译应用程序代码

内存模型
理解C语言的内存模型memory model),这有助于理解Objective-C的内存模型及其“引用计数”(reference counting)机制工作原理。若要理解内存模型,则需明白:Objective-C语言中的指针用来指示对象的。想要声明一个变量,令其指代某个对象可用如下语法

NSString *someString = @"The string";

例如上述代码,声明一个someString 的变量,此变量指向NSString的指针。所有OC语言的对象都必须这样声明,因为对象所占内存总是分配在“堆空间”中,而绝不会分配在“栈”上。不能在栈中分配内存对象。

something变量指向分配在堆里的某块内存,其中含有一个NSString对象。也就是说,如果再创建一个变量,令其指向同一地址,那么并不拷贝该对象,只是这两个变量会同时指向此对象。

NSString *someString = @"The string";
NSString *anotherString = someString;

上述代码中:只有一个NSString实例,然而有两个变量只想此实例两个变量都是NSString*型,这说明当前“栈帧”里分配了两块内存,这两块内存里的值都是NSSring实例的内存地址
对象分配在栈上,而实例分配在堆中。
分配在堆中的内存必须直接管理,而分配在栈上用于保存变量的内存则会在其栈帧弹出自动清理

引用计数
OC将堆内存管理抽象出来了,不需要mallocfree来分配或释放内存对象所占内存。OC运行期环境把这部分工作抽象一套内存管理架构,名叫“引用计数”。

重点:

1.Objective-C为C语言添加面向对象特性,是其超集。Objective-C使用动态绑定的消息结构,也就是说,在运行时才会检查对象类型接收一条消息之后,究竟应执行何种代码,由运行期环境而非编译器来决定。
2.理解C语言的核心概念有助于写好Objective-C程序。尤其是要掌握内存模型指针


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

在编译一个使用了EOCPerson文件时,不需要知道EOCEmployer类的全部细节,只需要知道有一个类名叫EOCEmployer就好。因此可以头文件中“向前声明”该类

@class EOCEmployer;

实现文件中需要引入EOCEmployer类的头文件,因为若要使用后者,则必须知道其所有接口细节。代码如下

#import "EOCPerson.h"
#import "EOCEmployer.h"

@implementation EOCPerson

@end

将引入头文件时间尽量延后,只有在确有需要时才引入,这样就可以减少类的使用者所需引入的头文件数量,因为一旦引入就会引入该头文件的所有内容,若此过程持续下去则会引入许多根本用不到的内容,增加编译时间

向前引用

1.解决了这两个类相互引用问题
相互引用:有两个类,它们都在头文件中引入了对方的头文件,两个类都进行各自的引用解析,这样就会导致“循环引用”(chickenandegg situation)。虽然我们使用#import而非#include不会导致死循环,但是这意味着两个类中有一个类无法被正确编译。

2.但是,有时候就必须引入头文件,比如继承以及遵循的协议


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

编写OC程序时,总会用到某几个类,它们属于Foundation框架。虽让从技术上来说,不用Foundation框架也可使写出OC代码,但实际上却要经常使用到此框架。这几个类是NSString、NSNumber、NSArray、NSDictionary。从类名即可看出各自所表示数据结构

NSString* someString = @"Effective Objective"

有时需要整数浮点数布尔值封入OC对象中。这种情况下可以用NSNumber类。

不使用字面量:

NSNumber *somenumber = [NSNumber numberWithInt:1];

使用字面量:

NSNumber *number = @1;

优点:使对象变得更整洁

创建数组时不使用字面量语法

NSArray *array = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", nil];

使用字面量:

NSArray *array = @[@"1", @"2", @"3", @"4"];

用字面量在取某个下标对应的对象时更为容易。

对于字面量的话,需要注意的是,如果字面量初始化的有nil,就会报错,并且还需要注意,字面量初始化默认的是不可变的,如果需要初始化可变类型容器,就不能使用字面量进行初始化

字典”是一种映射数据结构,可向其中添加键值对。

不使用字面量语法:

NSDitionary* personData = [NSDictionarydictionaryWithObjectivesAndKeys:@"Matt",@"firstName",@"Galloway",@"lastName",[NSNumber numberWithInt:28],@"age",nil];

使用字面量语法:

NSDictionay* personData = @{@"firstName":@"Matt",@"lastName":,@"Galloway",@"age":@28};

优点:字典中的对象和键必须都是OC对象,所以不能把整数28直接放进去而要封装在NSNumber实例中才行。使用字面量语法只需在数字加一个@字符即可。

字典按照键访问值:

NSString* lastName = personData[@"lastName"];

如果数组字典对象是可变的,也可通过下标来修改元素值。

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

定义常量时,比预处理更好的办法是用stactic const

定义常量位置很重要。预处理指令常量名不该使用在头文件中,因为所用引入了这个头文件的其他文件都会出现这个名字其实就连用static const定义的常量也不应该出现在头文件中,因为OC没有名称空间”这一概念,这样做相当于声明了一个全局变量

const声明的变量不可变,static修饰符意味着该变量仅在定义此变量的编译单元中可见。编译器每收到一个编译单元(指每个类的实现文件),就会输出一份“目标文件”。

想定义一个全局常量的做法
定义使用extern关键字

在头文件

extern NSString *const string;

实现文件

NSString *const string = @"hhhh";

要点总结


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

  1. 枚举enum只是一种常量命名方式枚举只是一种常量命名方式,某个对象所经历的各个状态、定义选项或者把逻辑含义相似一组状态码都可以放入一个枚举集里。
  2. 编译器会为枚举分配独有的编号,从0开始,每个枚举递增1。也可以手动设置某个枚举成员对应的值,后面的枚举一次加1。实现枚举所用的数据类型取决于编译器,不过其二进制位bit)的个数必须能完全表示下枚举编号才行(例如最大编号是2,所以使用一个字节char类型即可)
  3. 可以指明枚举用的何种底层数据类型,这样编译器清楚底层数据类型的大小,可以向前声明枚举类型。

要点总结

原文地址:https://blog.csdn.net/weixin_61558111/article/details/128595032

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44560.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注