设为首页 加入收藏

TOP

Objective-C中的属性(property)(一)
2015-01-22 21:30:36 来源: 作者: 【 】 浏览:113
Tags:Objective-C 属性 property
Objective-C中的属性(property)
?
它组合了新的预编译指令和新的属性访问的语法,新的属性功能显著减少了必须编写的冗长代码的数量。
下面我们来比较下面的代码
?
复制代码
//第一种声明方法
-(void)setRainHandling:(float) rainHanding;
?
-(float) rainHandling;
?
?-(void)setSnowHandling:(float) snowHandling;
?
-(float) snowHandling;
?
//第二种声明方法
@property float rainHandling;
?
@property float snowHandling;
复制代码
?
?
以上两段代码的作用是完全一样的,由此我们可以得出属性的作用是:
?
@property预编译指令的作用是自动声明属性的setter和getter方法,事实上,属性的名称不必与实例变量的名称相同,但大多数情况下它们是一样的。
我们知道了函数的settter和getter方法的声明,但是如何实现呢?我们接着看
?
复制代码
//第一种实现方法
-(void)setRainHandling:(float) rh
{
? ? rainHandling =rh;
}
?
-(float) rainHandling
{
? ? return rainHandling;
}
?
-(void)setSnowHandling:(float) sh
{
? ? snowHandling =sh;
}
?
-(float) snowHandling
{
? ? return snowHandling;
}
//第二种实现方法
@synthesize rainHandling;
?
@synthesize snowHandling;
复制代码
?
?
我们的目的是彻底的删除setter和getter方法,用以上的两行代码就可以完全代替。
?
对于synthesize这种编译器的功能有以下几点需要说明:
?
@sythesize它表示“创建了该属性的访问代码”。当遇到@sythesize rainHandling;这行代码时,编译器将添加实现 -setRainHandling:和-rainHandling方法的预编译代码。
Cocoa的访问器编写实用工具和其他平台上的UI生成器可以生成源代码,这些源代码随后会被编译。但是@sythesize预编译指令不同于代码生成。你永远也不会看到实现-setRainHandling:和-ranHandling的代码,这些方法确实存在并可以调用。
在X-code 4.5以后的版本中,可以不必使用@sythesize了。
所有的属性都是基于变量的,所以在你合成setter和getter方法的时候,编译器会自动创建与属性名称相同的实例变量。如果你没有声明这些变量,编译器也会声明的。如果我们不去自己实现@sythesize,编译器会给我们生成一个下滑线(_)开头的实例变量。如在头文件的定义中写@property (copy) NSString name; 在其实现中会有一个_name的实例变量。
点表达式的妙用
?
Objective-C 2.0的属性引用了一些新的语法特性,使我们更加容易访问对象的属性,也就是点表达式。
如果点表达式出现了等号(=)的左边,该变量名称的setter方法将被调用。如果点表达式出现在了对象变量的右边,则该变量的getter方法将被调用。
点表达式只是调用访问方法的一种便捷方式,并没有什么神秘之处。
属性的扩展
?
assign //简单赋值,主要用于基本数据类型
copy //创建一个新的对象,新的对象和旧对象是独立的两个对象
retain //将对象计数器加1
readonly //表示只读属性 ?只会生成getter方法 不会生成setter方法
readwrite //默认值,表求生成setter和getter方法
nonatomic //非原子访问,不加同步 ,多线程并发访问提高性能 (对多线程的保护,防止在未写完,被另一个线程读取,造成数据错误)
名称的使用
?
  一种非常普遍的情况是属性的名称与支持属性的实例变量名称相同,不过,有时候你可能希望实例变量是一个名称,而公开的属性是另一个名称。
?
复制代码
//头文件的定义
#import "Tire.h"
//关于适应所有天气的Tire类的声明与定义
?
@interface AllWeatherTire : Tire
{
? ? NSString *tireName;
}
?
@property float rainHanding;
@property float snowHanding;
//用于给我们我的轮胎起一个名字
@property (copy)NSString *name;
?
//实现
#import "AllWeatherTire.h"
@implementation AllWeatherTire
@synthesize name = tireName;
?
- (NSString*)description
{
? ? NSString *desc;
?
? ? desc = [NSString stringWithFormat:@"AllWeatherTier:name is %@,%.1f,%.1f, %.1f, %.1f",
?
? ? ? ? ? ? self.name,self.pressure,self.treadDepth,self.rainHanding,self.snowHanding];
?
? ? return desc;
}
复制代码
?
?
  ? 在这里编译器仍创建-setName:和-name方法,但在其实现代码中用的却是tireName实例变量。不过这样做的话,编译的时候将会遇到一些错误。因为我们直接访问的实例变量已经被修改了。我们可以选择用搜索并替换的name的方式来解决,也可以将实例变量的直接调用改成用访问的方法。比如在init方法中把 name =@“Car” 改成self.name =@"Car".
?
自己动手有时更好
?
我们之前提到过属性是基于变量的,并且编译器会为你创建setter和getter方法。但是如果你不想要变量、setter和getter方法的话应该怎么办?
答案是使用@dynamic关键字。
如果你声明了dynamic属性,并且企图调用不存在的getter和setter方法,你将会得到一个错误。
复制代码
@property(readonly) float bodyMassIndex;
?
@dynamic bodyMassIndex;
?
-(float)body
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇c语言编写经验逐步积累3 下一篇0524.Objective-C中时间戳转换和..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: