类和对象
类型系统
引用类型 reference type
类class
指针 pointer
块 block
类型装饰
协议protocol
类别 category
拓展 extension
值类型 value type
基础数值类型
结构 struct
枚举 enum
类 class vs 结构 struct
类型与实例
类与对象
结构与值
类-引用类型
位于栈上的指针(引用)
位于堆上的实体对象
结构--值类型
实例位于栈中
空间分析
运行时的内存模型
对象的空间分析
对象:栈上存储(引用),堆上存储真正的对象
值的空间分析
值:实例(值)内存直接存储于栈空间
栈(stack)
栈:存储值类型
1.无arc负担,由系统自动管理,以执行函数为单位
2.空间大小编译时确定(参数+局部变量)
3.函数执行时,系统自动分配一个stack
4.函数执行结束时,系统自动分配一个stack
5.函数之间通过拷贝值传递
6.具有局部性,大小有限额,超出会stack overflow
堆:存储引用类型对象
1.创建对象时手动请求分配
2.释放由运行时arc机制自动释放(确定时)
3.函数之间通过拷贝引用(指针)传递
4.具有全局性,总体无大小限制(受制于系统内存整体大小)
数据成员:属性与实例
数据成员data member 描述对象状态
实例变量 instance variable
属性 property
函数成员 function member 描述对象行为
方法method
初始化init
析构器dealloc
属性:property
属性表达实例状态,描述类型对外接口。🆚直接访问实例变量,属性可以做更多控制。
默认情况下,编译器会为属性定义propertyName自动合成:
一个getter访问器方法:propertyName
一个setter访问器方法:setPropertyName
一个实例变量_propertyName
可自定义访问器方法,也可以更改访问器方法名,或实例变量名。
可以使用静态全局变量(c)+类方法,模拟类型属性
实例变量 instance variable
可以定义实例变量,而不定义属性。只有实例变量,没有类变量。
如果同时自定义getter和setter访问器方法,或者针对只读(readonly)属性定义了getter访问器方法,编译器将不再合成实例变量。
在类内一律使用属性来访问,类内大多也通过self使用属性访问。
初始化器init,析构器dealloc和自定义的访问器方法使用实例变量访问
实例变量的生存周期
实例变量的存储:跟随对象实例存储在堆上
值类型实例变量直接“内嵌”在对象实例中。跟随对象实例内存释放而被释放。
引用类型实例变量通过指针“引用”堆上的引用类型实例,arc针对引用进行计数管理,自动释放引用计数为0的对象。
属性描述特性attribute
属性描述特性attribute可以指定属性不同环境下的不同功能。
读写特性
readwrite(默认)读写属性
readonly只读属性
多线程特性
原子性atomic(默认)
非原子性 nonatomic
内存管理特性
arc环境
强引用strong(默认)
落引用weak阻止循环引用
拷贝属性copy创建独立拷贝
其他情况
retina
assign
unsafe_unretained
函数成员:方法
类型成员type member
数据成员 data member 描述对象状态
1.实例变量 instance variable
2.属性 property
函数成员 function member描述对象行为
方法 method
初始化器 init
析构器 dealloc
认识方法method
函数:代码段上的可执行指令序列
1.全局函数(c语言函数)
2.成员函数(obic方法)
方法是类的成员函数,表达实例行为或类型行为。
所有方法默认为公有方法,没有private或protected方法
动态消息分发:方法调用通过运行时动态消息分发实现,在对象上调用方法又称为向对象发送消息。
实例方法--表达实例行为,可以访问-()
1.实例成员(实例属性,实例变量,实例方法)
2.类型方法,静态变量
类方法--表达类型行为,访问权限:+()
可以访问:类型方法,静态变量
不能访问:实例成员(实例属性,实例变量,实例方法)
self指针对实例方法的处理:传递的是实例对象的指针
对类方法的处理:对类的一个表示
方法参数:
1.如果参数类型为值类型,则为传值方式。
如果参数类型为引用类型,则为传指针方式。
2.方法可以没有参数,也可以没有返回值
3.如国方法有参数,方法名约定包含第一个参数名,从第二个参数开始需要提供外部参数名。
4.调用时,第一个参数名忽略,但后面的参数名必须显式标明。
初始化器
初始化器用于初始化对象实例或者类型,是一个特殊的函数。
对象初始化器:-(id) init 可以重载多个?
类型初始化器:+(void)initalize 只能有一个
析构器用于释放对象拥有的资源,无返回值的函数
对象析构器-(void)dealloc 只能又一个
没有类型析构器
对象初始化器
初始化对象实例时,init通常和dealloc搭配使用。
alloc所做的事情--NSObject 已实现:
在堆上分配合适大小的内存。
将属性或者实例变量的内存置0.
init所做的事情--可以自定义
1.调用父类初始化器[super init](前置调用)
2.初始化当前对象实例变量 _name(实例变量),不使用属性
new相当于调用alloc/init的无参数版本
类初始化器 initalize负责类别级别的初始化。
initalize在每个类使用之前被系统自动调用,且每个进程周期中,只背调用一次。
子类的initalize会自动调用父类的initalize(前置调用)。
对象析构器
对象析构器dealloc负责释放对象拥有的动态资源:
自动实现:1.arc将负责对象属性引用计数减持
手动实现:2.释放不受arc管理的动态内存,如malloc分配的内存
手动实现:3.关闭非内存资源,如句柄(),网络端口...
dealloc 由arc根据对象引用计数规则,在释放对象内存前自动调用。
子类的dealloc 会自动调用父类的dealloc(后置调用)。
面向对象三大特征
封装encapsulation
隐藏对象内部实现细节,对外仅公布公共接口访问
继承 inheritance
一个类型在另外类型基础上进行的拓展实现。
多态 polymorphism
不同类型针对同一行为接口的不同实现方式。
继承inheeritance
每一个类只能有一个基类,子类会自动继承基类的:
实例变量
属性
实例方法
类方法
所有类的根类NSObject
继承的两层含义:
成员复用:子类复用基类成员
类型抽象:将子类当作父类来使用(ia-a关系准则?)
多态 Polymorphism
多态:子类在父类的统一接口下,表现不同的实现方式。
子类重写(override)父类同名同参数方法:子类只可以重写父类方法
方法名相同,参数不同:oc不支持方法的重载。
在子类的代码中可以使用super来调用基类的实现
self具有多态性,可以指向不同子类
super没有多态性,仅指向当前父类。
继承中的init和dealloc
初始化器 init
子类自动继承基类的初始化器。
子类可以重写基类的初始化器,此时子类初始化器必须首先调用基类的一个初始化器(手工调用)。
析构器dealloc
子类可以选择继承其基类的析构器,或重写基类析构器
子类析构器执行完毕后,会自动调用基类析构器(后置调用,且不支持手工调用)
子类析构器自动具有多态性
tips:尽量在父类init和dealloc中调用子类重写的方法。