OC简介
语言简介
- 完全兼容C语言
- 通过LLVM(LowLevelVirtualMachine)编译器架构,支持与swift的双向互通


时空角
clang或gcc命令行 ```shell clang -fobjc-arc HelloWorld.m -o HelloWorld
gcc -v gcc main.c => a.out ./a.out
编译
cc -c mian.c => main.o
链接,增加启动代码
cc main.o => a.out
执行
./a.out
<a name="yka4X"></a>### IDE- Xcode- 构建大型项目,追求质量和代码组织<a name="29DC2"></a>## 代码基础- Mac上不能直接写NTFS格式的硬盘,需要TuxeraNTFS软件- C语言开发步骤1. 编码 touch main.c2. 编译 cc -c main.c => main.o3. 链接 cc main.o => a.out (源码增加启动代码)4. 执行 ./a.out- .h是头文件,.m是实现文件- #import优于#include,解决了循环依赖的问题<a name="REOpx"></a># 类与对象<a name="PXTWt"></a>## 类型系统- 引用类型ReferenceType- 类class- 指针pointer- 块block- 值类型ValueType- 基础类型- 结构struct- 枚举enum<a name="Mg78X"></a>## 类型装饰- 协议 protocol- 类别 categary- 扩展 extension<a name="0vrD4"></a>## 类与结构| | 类 | 结构 || --- | --- | --- || 类型与实例 | 类与对象 | 结构与值 || 类型 | 引用类型 | 值类型 || 面向对象 | 有属性、有方法(-表示实例方法 +表示类方法) | 只有属性、没有方法 || 内存结构 | 引用位于栈上的指针,指向堆上的对象 | 实例直接位于栈中 || 空间分析图 | 下图1 | 下图2 |<br /><a name="Qqlfv"></a>## 堆栈<a name="8e34r"></a>###| 堆 | 栈 || --- | --- || 存储引用类型对象 | 存储值类型 || 创建对象时需要手动请求分配空间,释放由运行时ARC机制自动释放 | 无ARC负担,由系统自动管理,以函数为单位,函数执行时自动分配stack,执行完毕自动回收 || 具有全局性,空间大小受系统限制,超出会报OOM | 空间大小编译时确定(参数+局部变量)具有局部性,大小有限额,超出会报SOF || 函数之间通过拷贝引用传递 | 函数之间通过拷贝值传递 |<a name="XHXYL"></a># 类型成员<a name="PCS4w"></a>## 数据成员DataMember,描述对象状态- 实例变量 instanceVariable- 只在类内部访问- 生存周期- 实例变量的存储是跟随对象实例存储在堆上- 值类型的实例变量内嵌在对象实例上,跟随对象实例的释放而被释放- 引用类型的实例变量通过指针“引用”堆上的类型实例- 属性 property- 描述对外接口,默认编译器会为属性定义propertyName自动合成以下内容- getter访问器 propertyName- setter访问器 setPropertyName- 实例变量 _propertyName- 类外部使用一律使用属性访问- 类内大多通过self使用属性访问,只有以下情况使用实例变量访问- 初始化器 init- 析构器 dealloc- 自定义访问器方法- 属性的描述特性attribute,指定属性不同环境下不同功能- 读写特性- readwrite 默认- readonly- 多线程特性- atomic 默认- nonatomic- 内存管理特性- ARC环境- strong 默认- weak 弱引用,阻止循环引用,防止内存泄漏- copy 创建独立拷贝,防止引用连带- 其他情况- retain- assign- unsafe_unretained<a name="ZHQ71"></a>## 函数成员FunctionMember,描述对象行为- 方法 method- 分类- 全局函数(C语言函数)- 成员函数(OC方法)- 所有方法默认为公开方法,没有private或protected- 动态消息分发:方法调用通过运行时动态消息分发实现,在对象上调用方法又称给对象发送消息- 修饰符号- -表示实例方法,可以访问- 实例变量- 实例属性- 实例方法- 类静态变量- 类方法- +表示类方法,可以访问- 类静态变量- 类方法- 方法参数- 如果参数为值类型,则为传值方式- 如果参数为引用类型,则为传指针方式- 方法可以没有参数,也可以没有返回值- 如果方法有参数,方法名约定包含第一个参数名,从第二个参数开始需要显式提供外部参数名- 调用时第一个参数名忽略,后面的参数名显式标明- 动态方法调用机制——消息分发表,id类型的obj可以通过指针指向的methodlist找到真正的方法内存地址,即可以通过id类型调用方法- 初始化器 init- 对象初始化器- -(id) init- 可以重载多个- 初始化对象实例时,init通常和alloc搭配使用- alloc- NSObject已实现,不用自定义- 在堆上分配合适大小的内存- 将属性或实例变量的内存置为0- init- 需要自定义- 首先调用父类的初始化器[super init]- 初始化当前对象的实例变量,这里不能使用属性- new 调用相当于alloc和init的无参版本```objectivec-(id) initWithName:(NSString*) name WithPages(int) pages{self = [super init]if(self){_name = [name copy]_pages = pages}return self;}
- 类型初始化器
- +(void) initialize
- 只能有一个,负责类型的初始化
- 在每个类使用之前被系统自动调用,且每个进程周期只能被调用1次,无法手动调用
- 子类的initialize会自动调用父类的initialize
- 析构器 dealloc(用于释放对象拥有的资源,是一个没有返回值的函数)
- 对象析构器
- 一个类型在另外类型基础上进行的扩展实现,所有类的基类NSObject
- 每个类只能有一个基类,子类自动继承基类的
- 实例变量,使用->访问
- 属性
- 实例方法
- 类方法
- 继承的两层含义
- 成员复用,子类复用基类成员
- 类型抽象,将子类当作父类来使用【IS-A关系】
- init
- 子类自动继承父类的初始化器
- 子类可以重写父类的初始化器,此时必须手动调用父类的一个初始化器
- dealloc
- 子类可以选择继承父类的析构器,也可以重写
- 子类析构器执行完毕后会自动调用父类的析构器(后置调用且不支持手动调用)
-
多态
不同类型针对同一接口的不同实现方式
- 子类在父类统一行为接口下表现出不同的实现方式
- 重写和重载
- 重写:子类重写父类同名同参方法:子类只可以重写父类方法
- 重载:方法名相同,参数不同:OC不支持重载
- 子类的代码中,可以使用super来调用父类的实现
- self具有多态性,可以指向不同的子类
- super没有多态性,仅指向当前父类
