Objective-C之Property

 在Objective-C中引入了属性这个概念,当然了这东西并不是Objective-C首创而且独有的特性,例如C#里边也有属性的概念,因此学过C#的朋友应该很容易就掌握Objective-C中的属性这个知识点。

    1 OverView

    在java中,我们可能经常通过getter/setter来访问一个对象的成员变量,为什么不直接访问对象内部的成员变量了,这样不是更简单吗?因为通过getter/setter的这种模式来间接地访问对象的成员变量,符合了类的封装性的原则。这就好像汽车一样,你不是直接操作汽车的引擎、油门阀、制动器来驾驶汽车,因为这些东西(成员变量)都被汽车(类)的设计者封装起来了,不直接向外界暴露,而是通过提供诸如像方向盘、刹车的踏板、油门踏板(getter/setter)这样的接口来供外界使用,这样就隐藏了类内部的一些实现细节。。

    既然写getter/setter方法有这么多好处,好吧,那我们以后设计每个类都这样做,结果悲催了,因为有一天公司叫你设计一个类,而那个类有10W个成员变量,这就意味着你要写10W对getter/setter对(当然了现实中可能不存在这样子的极限情况)。想想都觉得好蛋疼。好吧,对于这样中情况,Objectiv-C的设计团队隆重地在其语言特性中提供了Property的机制,以减轻我们的工作量,同时也使得代码变得更简洁。

    Objective-C教导我们:你要是想用这种机制来偷懒,好吧,你必须提供以下信息才可以哦:

  一、属性的类型和名称(废话,不然编译器肿么自动帮你生成getter/setter)

  二、指顶Property的属性,以控制生成getter/setter的具体行为。

2 Property的声明和实现

要在Objective中使用Property,那么我们得分两步走:声明它然后定义它。

2.1 Property的声明

我们可以通过关键字@property来声明属性,而且属性的声明可以出现在类中的方法列表的任何位置,也可以出现在协议声明的任何位置。

格式:@property(属性集)type name;

2.2 属性集

2.2.1 读写性:

readwrite(读写属性:指示编译器生成getter和setter方法,此属性是默认的)

readonly(只读属性:指示编译器只生成getter方法)

2.2.2 针对setter方法的属性

strong:强引用,相当于retain。

weak:弱引用,相当于assign,且弱引用所指向的对象被释放后,指向该对象的指针会被自动置为nil.

copy:指定setter方法的参数采用深度复制到目标对象上,但是setter方法的参数必须要实现NSCopying协议(协议只是Objective-C中的叫法,即接口啦)

assign:指定setter方法中只是简单的复制,此属性为默认属性。例如对一些基础类型的属性可以采用它,如int,float,NSInteger....

retain:在assign基础上,再保留setter参数的一个引用,造成的影响是setter参数中的对象的保留计数值增加了1

此属性适用于参数为某一个对象的指针。如NSString*,

2.2.3Atomicty即原子性,

nonatomic属性:指定对属性的访问是非原子性的,默认是atomic原子性的。

atomic属性:指定对属性的访问时原子性的。此属性为默认值

一般为了在多线程环境中,提供健壮的属性访问,可以将property的属性指明为atomic,这样就不会再get的同时,也有另外一个线程在对同一个property进行set操作。但这样做虽然安全了,但牺牲了效率。鱼与熊掌不可兼得呀。

如果你指定了property的属性集为strong、copy或者是retain,但没有指定nonatomic,那么在引用计数的环境中,编译器会为该property生成类似于如下的getter方法:

[_internal lock]

id result = [[value retian] autorelease];

[_internal unlock]

return result;

2.2.4 getter和setter属性

我们可以自定义getter和setter的名字

eg: @property(getter=MyName,setter=setMyName) NSString* name;    

这样编译自动生成的getter和setter方法名就会按你指定的那样:setMyName和MyName;

3 property的实现

我们可以通过@synthesize 或者@dynamic来通知编译器按照property的声明部分指定的条件来生成对应的getter/setter。

3.1 @synthesize

@synthesize 属性名[=成员变量名]; “[]”表示里面的内容是可选的。。

第一种形式:不带中括号中的内容的定义方法

eg: @interface Student:NSObject

{

    NSString* name;

}

@property(nonatomic,retain) NSString* name;

@end

@implementation Student

@synthesize name;    //自动生成setName和name方法

@end

第二种方式

在声明部分改为:@property(nonatomic,retain)NSString* myProperty;

@implementation Student

@synthesize myProperty=name;    //=name表示在合成的setMyProperty和myProperty中操作的成员变量是name;

@end

3.2@dynamic

关键字@dynamic其实就是告诉编译器在运行时动态地去找setter或者getter方法。因为代码由我们自己实现了或通过继承而来。(个人理解)

eg:

3.2.1@dynamic小技巧:

我们可以通过它在子类中改变父类中的只读属性。例如:

@interface A:NSObject

{

    int nTmp;

}

@property(assign,readonly) int nTmp;        //声明一个只读属性

@end

@interface B:A

@property(readwrite,assign) nTmp;          

@end

@implementation B

@dynamic nTmp;

-(void)setNTmp:(int)newNTmp

{

    nTmp = newNTmp;

}

@end


转载于:https://my.oschina.net/leojack/blog/91586

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值