在上一篇博文中,咱们有拿一个简单的“汽车模型”来说解复合关系。在今天的这篇博文中,咱们将接着上一次的例子,讲解下存取(accessor)方法的使用。所谓存取方法,就是用来读取或改变某个对象属性的方法。若是添加一个方法去改变Car对象中的engine对象变量,那它就是一个存取方法。数组
存取方法分为两种:setter方法和getter方法。setter方法,是为对象中的变量赋值。getter方法,是经过对象自己访问对象属性。安全
在Objective-c中,Cocoa框架在定义存取方法的时候,有相关的规定:框架
(1). setter方法,根据它的所要去改变的属性名称来命名,并在前面加set前缀。如:setEngine,setTire等。函数
(2). getter方法,则是以其返回的属性名称来命名,不要将get前缀加到getter方法名前面。由于在Cocoa中,get前缀有其余的用途。通常意味着这个方法会将你传递的参数做为指针来返回数值。性能
介绍完了基本的概念和定义的规则。下面,咱们就来修改“汽车模型”,给汽车的engine和tire设置存取方法。学习
首先,先在Car对象定义中添加engine和tire的存取方法:atom
1 @interface Car : NSObject 2 { 3 Engine *engine; 4 Tire *tires[4]; //四个轮子,定义一个四个数的数组。 5 } 6 -(Engine *) engine; 7 -(void) setEngine:(Engine *) newEngine; 8 -(Tire *) tireAtIndex:(int) index; 9 -(void) setTire:(Tire *) tire atIndex:(int) index; 10 -(void) drive; 11 @end // Car
因为,tire有四个子集,因此这里还添加了一个atIndex参数,表示第几个轮子。接下来,实现Car中定义的存储方法:spa
1 @implementation Car 2 -(void) setEngine:(Engine *) newEngine 3 { 4 engine = newEngine; 5 } 6 7 -(Engine *) engine 8 { 9 return (engine); 10 } 11 12 -(void) setTire:(Tire *) tire 13 atIndex:(int) index 14 { 15 if(index<0 || index>3) 16 { 17 NSLog(@"bad index(%d) in setTire:atIndex", 18 index); 19 exit(1); 20 } 21 tires[index] = tire; 22 } 23 24 -(Tire *) tireAtIndex:(int) index 25 { 26 if(index<0 || index>3) 27 { 28 NSLog(@"bad index(%d)in tireAtIndex:", 29 index); 30 exit(1); 31 } 32 return (tires[index]); 33 } 34 35 -(void) drive{ 36 NSLog(@"%@",engine); 37 NSLog(@"%@",tires[0]); 38 NSLog(@"%@",tires[1]); 39 NSLog(@"%@",tires[2]); 40 NSLog(@"%@",tires[3]); 41 } 42 @end
为了传入的index参数不符合条件,使得超出数组,咱们作了简单的判断。最后,咱们修改main主函数:线程
1 int main(int argc, const char * argv[]) 2 { 3 Car *car = [Car new]; 4 Engine *engine = [Engine new]; 5 [car setEngine:engine]; 6 for(int i=0;i<4;i++) 7 { 8 Tire *tire = [Tire new]; 9 [car setTire:tire atIndex:i]; 10 } 11 12 [car drive]; 13 return 0; 14 }
这时,咱们发现:以前在Car中定义的init初始化方法,这边移除掉了。因为Car如今本身定义了访问engine和tires变量的方法。因此,不须要init方法来建立。而是直接在主函数中建立Engine和Tire。指针
运行结果和以前的没有区别:
经过这个简单修改的例子,但愿你们对Cocoa框架中的存取方法的使用方法有更深的了解。
2014.12.07 后续更新部分
在这几天的学习中,发现Objective-C在实际的使用了,不少都是用合并存取方法来实现。全部,这里,我想扩展给你们一块儿分享下。
让系统自动合并setter和getter只要两个步骤:
(1). 在类接口部分使用@property指令定义属性。
(2). 在类实现的部分使用synthesize指令声明该属性便可。
全部,上面例子中定义Engine的存取方法咱们能够修改为如下代码:
原来的setter方法和getter方法能够合并改为:
1 /* 3.Car */ 2 @interface Car : NSObject 3 { 4 Engine *engine; 5 Tire *tires[4]; //四个轮子,定义一个四个数的数组。 6 } 7 @property(nonatomic)Engine* engine; 8 @end // Car
实现方法只要这样:
1 @implementation Car 2 @synthesize engine; 3 @end;
在使用@property指令的时候,后面会带上一些参数,具体的做用这边大体介绍下。要想深刻了解,能够以后本身百度之。
atomic(nonatomic):指定合成的存储方法是否为原子操做。即:主要指是否线性安全。aomic能够保证对象数据完整性,可是线程的安全性下降。nonatomic能够提升存储方法的访问性能。
copy:当调用setter方法对成员变量赋值的时候,会将被赋值的对象复制成一个副本,再将该副本赋值给成员变量。copy指令能够避免当计数器的值为0的时候,对象被清除。
readonly:指示系统只合成getter方法,再也不合成setter方法。即:定义的方法只读,不能给赋值。
readwrite:是默认值,指示系统须要合成setter,getter方法。
retain:当把某个对象赋值给该属性时,该属性原来所引用的对象的引用数减1,被赋值对象的引用数加1。(ARC内存机制中用到)
retainCount:获取引用的对象的引用数。
weak:指示符指定该属性对被赋值对象持有弱引用。即:即便该弱引用指向被赋值的对象,该对象也可能被回收。
strong:指示符指定该属性对被赋值对象持有强引用。即:只要该抢引用指向被赋值的对象,那么该对象就不会自动回收。