日常开发OC基础笔记

OC的属性

2015-10-03  本文已影响2434人  PeterKock

OC的属性机制提供了一个默认的设置器访问器的实现

现在先了解OC的实例变量作用域

@protected: 受保护的,这个实例变量只能在该类和这个类的子类中被访问,(可以被子类继承)其他类无法访问。不写的情况下默认为这个属性。
@private:私有的,这个实例变量只能再该类的中访问,其他类不能访问,包括它的子类继承同样无法访问
@public:公有的,这实例变量谁都能访问。

新建一个项目用来测试变量的作用域
新建一个Student类


新建Student类

接下来在接口文件中定义实例变量


Student.h

接下来在创建一个SmallStudent类文件,继承自Sutudent类


新建类
接口文件中查看继承

在子类文件中的接口文件做一个测试方法test声明


SmallStudent.h

在子类文件中实现文件.m做测试方法的操作
-在文件中可以看到,子类可以使用父类中的公有的,和受保护的实例变量,但是无法使用父类中私有的实例变量。
-在编辑的时候有有错误的提示,在实例变量名上有一条红线,就是无法使用的表示。


Student.m

最后在main.m文件中在进行测试,记得添加头文件


main.c

受保护的实例变量只能在该类和继承的子类中使用,所以实例变量中只有公有的能被使用。

总结:
为了隐藏实例变量,我们可以使用@protected(受保护)和@private(私有)关键字。
通过类的实例变量的作用域来限制实例变量的访问范围。


现在使用设置器和访问器(存取的方法)访问实例变量

在使用@protected变量和@private实例变量的时候,要进行信息的交换,这是就需要用到存取方法(getter和setter)

取实例变量的值用getter方法
设定或修改变量的值用setter方法

新建项目,在项目中做一个Student的类
在类的接口文件中写两个私有的实例变量(默认不写就是私有的 和行为部分的方法

Student.h

在类的实现文件中对方法进行重写和方法的具体实现

Student.m

最后在mian.m文件中使用setter 和getter方法


main.m

总结:
-使用set和get 方法间接的方法来访问实例变量,在封装隐藏变量的同时,提供饿了访问的方法。
-同时,我们也可以在setter方法中(存方法)对实例变量的值进行合法性的的判定。


属性的定义和使用

使用setter(存方法)和getter(取方法)在数据量大的时候,不适合使用,因为需要手写许多的重复性的setter 和getter代码。这时就需要用到OC中自动产生getter和setter方法。这种方法就是属性
同样的新建一个项目,在项目中同样新建一个Student类
在类的接口文件.h 中使用@property符号对方法进行声明。

@propert语句就相当于起到了getter和setter方法声明的作用

-基本类型的实例变量,只需要加上@property就可以了。
-如果需要的类型是哪类对象的实例变量,只需要加上相应的描述,如:

(nonatomic,strong)

两个接口文件的对比

接下来在实现文件中,用@synthesize符号来是实现和替代相应的方法实现。

@systhesize一条语句就祈祷了getter和setter的方法实行的作用。

两个实现文件的对比

最后,在mian.m 文件中实现。这里就便不再需要修改了。


mian.m

在这里还可以进行进一步的简化
类的接口文件中.h 中的实例变量声明可以省略。


Student.h

类的实现文件中.m 中@synthesize可以省略,修改重写方法


Student.m

因为把@synthesize注释掉了,系统会自动提供一个下划线开头的实例变量,因此,需要把类的实现文件中的市实例变量修改过来。


点语法

点语法和C语言的的结构体操作类似,只是操作类似,并不是C语言的结构体。
在mian.m文件中的操作可以用到点语法。


main.m

在类的文件中同样可以用点语法,这是就要使用self.


property的语法

存取方法
系统默认的的存取方法名propertyName和setPropertyName。
如:Student类中的name,对应的存取方法名称是name和setName。

getter=getterName
指定getter自定义方法的名称,自定义方法必须返回类型匹配的值,并且没有参数。
如:
@property(getter=getName)NSString *name;

setter=setterName
指定setter自定义方法的名称自定义方法必须只有一个类型匹配的参数,并且返回void。
如:
@property(setter=newSetName)NSString *name;

如果改变了getter和setter方法的名称,必须提供自定义的方法。
可读写性
可读写性确定了属性是否有setter方法。

readwrite
指明属性是可读写的(默认值),可省略不写
如:
@property(readwrite)NSString *name;

readonly
指明属性是只读的,系统会产生getter方法,不会产生setter方法。
 如:
@property(readonly)NSString *name;

只读的属性,如果想通过点语法给它赋值,会得到编译错误。
setter语义
用于setter的方法,属于互斥的。

strong     表示强引用关系,拥有目标对象的所有权
weak       表示弱引用关系,不拥有目标对象的所有权。
           当目标对象被销毁之后,属性值会被自动设为nil。
copy       会通过copy复制对象,之前的对象会接受到释放的信息。
assign     表明采用简单的赋值方法(默认方式)
retain     会通过retain来持有目标对象,之前的对象会接受到释放的消息。

原子操作
通过这些来判断是否采用了原子操作

atomic      原子操作,属于默认值。在多线程环境中,把方法设定为原子操作,可以提供      可靠的属性存取方法。
nonatomic   非原子操作,会简单的操作属性值。可以加快属性值存取的速度,但是无法保证在多线程环境下不会出错。

属性的重定义
可以通过重写把制度(readonly)的属性修改为可读写(readwrite)的。可以通过在延展协议和子类中重新定义。
重定义的应用模式

从一个不可变的父类产生可变的子类
一个类有只读的公开的属性和可读写的私有的属性

Student类接口文件.h 子类MutableStudent

或者通过延展修改Student类,让Student拥有一个公开只读name,有一个私有的可读写的name


实行的使用过程中注意:
1.没使用@synthesize的时候,系统会自动生活城类似_name格式的变量,但是我们仍然使用name,这时的_name和name是两个不同的变量。
2.点语法中如果使用了C语言的结构体代码,当对象为nil的时候,调用C结构体会使程序崩溃。
3.系统自动产生的get方法,其实不是get开头的,如果使用类的aName =[stu1 get Name ];Xcode会警告,运行时会出错。

上一篇下一篇

猜你喜欢

热点阅读