聊聊属性的隐藏@property和@synthesize

转载请注明出处,谢谢.http://blog.csdn.net/cloosen/article/category/1191706

该文章会不定时更新,因为毕竟一次把他写全有点难,有的东西忘了写了什么的,如果想起来会补充进去,如果大家有什么疑问可以留言,如果我了解会不定时回答的,3Q.


题外话:哈哈这几天水stackoverflow水上瘾了,每天都要回答几个问题,昨天week积分排名666,很幸运的一个数字,哈哈,截下来做个保存,争取周末狂水两天,最好week排名挤进前500


OK,好了,说说属性这东西.

1)最正常最正常的coding方式无非就是:

.h文件

@interface MyClass : NSObject
{
    NSString *_myString;                      
}
@property (nonatomic,retain) NSString *myString;

@end


.m文件

@implementation MyClass

@synthesize myString = _myString;
 
- (id)init
{
    if (self = [super init])
    {
        //your code
    }
    return self;
}

这种写法毫无疑问,最正统,你可以使用self.myString,外部类也可以访问你的myString属性,系统默认给你生成了get,set方法,当然了,你可以自己写set,get方法来覆盖系统默认生成的,以后的blog会专门介绍下set,get方法,可别小看这个,这个可是cocoa设计模式的一部分呢,这叫做访问器模式.你可能会想get,set那种小把戏就是忽悠忽悠初学者,你可能注意到了这句
@property (nonatomic,retain) NSString *myString;

nontomic这个大家都知道啥意思,就是当多线程访问的时候锁定线程,但是当你不写nontomic的时候,再去写set和get,估计绝大多数人都写不对.


2)稍微变化一下的写法

.h文件

@interface MyClass : NSObject
{
NSString *myString; 
}
@property (nonatomic,retain) NSString *myString;
@end


.m文件
@implementation MyClass
@synthesize myString;

- (id)init
{
if (self = [super init])
{
//your code
}
return self;
}



我很喜欢的一种写法,比较懒,当内部变量名和属性名一样的时候,@synthesize可以少写几个字,并且这样其实主要作用就是开一个属性给外部类调用,自己类内部不用self.myString,当然了你用也可以,但是我自己的爱好是绝对不用,否则有时候内存容易搞不清.之后的blog会简述一下self.myString和myString的区别的.

3)再变换一下
.h文件
@interface MyClass : NSObject
{
}
@property (nonatomic,retain) NSString *myString;
@end



.m文件
@implementation MyClass
@synthesize myString = _myString;

- (id)init
{
if (self = [super init])
{
//your code
}
return self;
}



没错,interface中没有定义NSStrng,但是这样能编译过,运行没问题,并且现在coding时候发现xcode生成的代码也是这样,原因是objective-C是运行时语言,在Objective-C 2.0之后即64位操作系统和ARM情况下,objective-C可以在runtime时动态的生成 _myString .但是在32位操作系统和PowerPC的情况下,这样会报错的. 外部类和函数可以活得该属性.并且在.m文件中可以用self.myString也可以直接用_myString.

4)readonly

.h文件
@interface MyClass : NSObject
{
NSString *myString; 
}
@property (readonly) NSString *myString;
@end



如果把一个属性设置为readonly,外部的类就只能get而不能对其进行赋值操作,直接只写readonly的话默认是retain的,当然也可以写成@property(nonatomic,readonly,retain) myString;如果在.m不进行其他的处理的话,在自己类的内部其也是readonly的,所以你自己也不能对其进行赋值操作,所以不想悲剧的话只能对.m文件进行处理.

.m文件
@interface MyClass ()
@property (nonatomic, retain, readwrite) NSString *myString;
@end
@implementation MyClass
@synthesize myString;

- (id)init
{
if (self = [super init])
{
//your code
}
return self;
}


@interface MyClass()是类别,也是一个设计模式,以后的blog会讲的 :-) .其相当于在.m内部定义了一个似有的myString,将.h中的给覆盖了,在.m文件中我们可以对myString进行读写操作,而外部的类只可以对该属性进行只读操作,这么写很好的体现了OOP的封装的特性.

5)外部不可见的属性.
.h文件
@interface MyClass : NSObject
{
}



.m文件
@interface MyClass ()
@property (nonatomic, retain) NSString *myString;
@end
@implementation MyClass
@synthesize myString;

- (id)init
{
if (self = [super init])
{
//your code
}
return self;
}



这种情况很常用,在.h文件中不写@property,外部类就无法访问该属性,而用类别大家肯定都很熟悉,写内部函数就要用类别,所以很容易理解,这个属性就是内部属性,然后.m文件可以对该属性进行任何操作,而不用暴露给使用者.体现了OOP的封装性.这么写通常会在.h文件中给外部类提供一个外部方法,即- (void)setString:(NSString *)myString,或者- (void)changeString:(NSString *)myString.主要作用其实就是给外部类一个设置myString的机会,eg.如我想让你设置我的title,但是又不想让你获取到,我就会用到这种方式,当然了,上例给出的两种写法还是有比较大的区别的,尤其是如果myString是我这个类的父类的一个属性时候,这两种写法就是天差地别了,因为外部类用了.myString会自动调用你的set方法,而不会调用你的change方法,所以还是建议写成后者,我当时就遇到了这个问题,当时用了一个多余的bool属性解决了问题,但是改成change后发现就可以把这个bool属性去掉了,如果对代码要求比较高的童鞋最好用后者那个change方法.


6)巨少见的隐藏属性.
.h文件
@interface MyClass : NSObject
{
}



.m文件
@implementation MyClass
{
NSString *myString; 
}

- (id)init
{
if (self = [super init])
{
//your code
}
return self;
}



没错是implementation , 没错,implementation居然可以这么用,不过我几乎没见过有人或者有demo是这么写得,看一下了解一下就行了,如果以后觉得有必要,还是会写篇blog的.有兴趣了解一下的童鞋可以看看苹果的这个文档,http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/objectivec/Chapters/ocDefiningClasses.html#//apple_ref/doc/uid/TP30001163-CH12-TPXREF126

以上就是我所掌握和了解的一些属性展示和隐藏的方法,但是有一点要说明的,尽管你认为你自己的类和属性已经封装很好了,但是外部类想要访问和修改你的私有变量还是可以的,那就是变态的KVO,KVO可以说是观察者方法中的一种,KVO以后的blog会详细介绍.另外加一句,前年,去年的时候发现github上的成员变量都写成 _myString,而去年左右的时候发现很多人都写成了myString,而最近看得代码和书,越来越多的人都喜欢这么命名了myString_ .哈哈,有兴趣的童鞋可以研究下,应该是对编译或者神马的有点好处.
PS:CSDN的代码粘贴真是比stackoverflow差的多的多啊,编辑了3次才编辑好


今天逛stackoverflow讨论起properties有个哥们给了个网址,哈哈,apple居然也有一节详细讲了属性这东西,有兴趣的童鞋可以看一下:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17.如果跟我这篇文章有什么不一样的地方,请以apple的文档为准.


转载请注明出处,谢谢.http://blog.csdn.net/cloosen/article/category/1191706

------------------by 郭大虎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值