实例变量
设置访问实例变量的方式:
@private:只能在声明它的类以及与该类型相同的其它实例中访问
@protected:相比于private,它可以在该类的子类的实例中访问,一般我们声明的实例变量没有做访问限制的,默认都是protected
@public:可以被任何代码访问
@package:主要用于库和框架类。可以被其它类实例和函数访问,但是在其所属程序包的外部,会被视为私有变量
实例变量可以在类的接口或者实现里声明,但是我们一般写在实现里。因为,写在公有接口里声明违反了OOP的封装原则。再说了,不还有属性嘛。
声明注意点:
如果使用了访问控制编译器指令,例子如下:(不太熟悉)
protection_directive ivar_declaration_list (到时候再去搜,反正和之前的不一样)
写法:
@private
int i;
int j;
类比协议的写法。
实例变量可以方便、直接访问对象的状态。但是在.h中声明了实例变量会暴露类的内部,这就违反了OOP的封装原则。
属性
OC里声明和定义是不同的概念,声明一般在.h中,实现一般在.m中。
属性与实例变量的区别:属性无法直接访问对象的内部状态,但是提供了访问这类数据的方便机制(点语法,getter和setter等)。
属性的特性见P18.
属性的定义:
1.显示定义(明确定义属性的setter、getter方法)
2.通过关键字补全(过时)
3.自动补全(主流)
4.动态生成(难点):
属性的访问器方法可以在运行时被委托或动态创建。使用@dynamic(动态)属性指令可以阻止编译器通过这种方式自动生成访问器方法。P19
如果使用了@dynamic来修饰某个属性,那么你必须得自己实现它的setter、getter方法。
属性有两种访问属性的机制:访问器(getter、setter)和点语法。注意:如果与属性关联的对象还没有完全创建好,就不要使用这些方法,而应该使用支持属性的实例变量。类内部的init方法dealloc会直接访问实例变量。在init方法里比方说有个属性叫做name,你要初始化它,你应该写成_name的形式而不是self.name的形式。
协议
协议可以用于定义对象能够发送哪些消息(通过设置遵守协议的属性)。
分类
为已存在的类增加功能。分类中的方法会被子类继承。
@interface 类的名称 (分类的名称)
//方法的声明
@end
扩展
扩展其实就是一种匿名的分类,我们经常用。
@interface Beauty
@end
@interface Beauty()
{
//实例变量的声明
}
//属性声明
//方法声明
@end
@implementation Beauty
@end
可以看出扩展和分类的区别就是扩展还可以声明实例变量和属性。