IOS Dev Intro - Property

103 篇文章 0 订阅


http://blog.csdn.net/totogo2010/article/details/7763139


1、简介: 

property是Objective-C的关键词,与@synthesize配对使用,用来让编译好器自动生成与数据成员同名的方法声明。@synthesize则是用来生成对应声明方法的实现。

1.1 property的语法格式:

@property (参数1,参数2类型名字;

这里的参数,主要有以下三种:

setter/getter方法(assign/retain/copy)

读写属性(readwrite/readonly)

atomicity(nonatomic)

1.2 三种方式的使用

assign/retain/copy  代表赋值的方式。

readonly关键字代表setter不会被生成, 所以它不可以和 copy/retain/assign组合使用。

atomicity的默认值是atomic,读取函数为原子操作。

1.2.1 copy/reain/assign 在其中选择一个来确定属性的setter如何处理这个属性。NSObject对象采用这个中方式。

1.2.2 一些特别的Object比如NSSstring使用copy

1.2.3 assign关键字代表setter直接赋值,而不是复制或者保留它。适用于基本数据类型,比如NSIntegerCGFloat,或者你并不直接拥有的类型,比如delegates

2、如何使用property

1.1  没有property和有property的对比

在头文件定义 obj。在.m文件中使用

[cpp]  view plain  copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface ViewController : UIViewController  
  4. {  
  5.     NSObject *obj;  
  6. }  
  7. @end  
[cpp]  view plain  copy
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];      
  4.     self.obj = nil;、  
  5. }  
提示不可用。

加上property

[cpp]  view plain  copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface ViewController : UIViewController  
  4. {  
  5.     NSObject *obj;  
  6. }  
  7. @property (nonatomic,retain) NSObject *obj;  
  8. @end  
编译能通过,运行,崩溃,提示错误  reason: '-[ViewController setObj:]: unrecognized selector sent to instance 0x6b6c480

那就是我们没事实现setter方法。

用@synthesize关键字实现getter 和setter。

在.m文件中

[cpp]  view plain  copy
  1. @implementation ViewController  
  2. @synthesize obj;  
  3. - (void)viewDidLoad  
  4. {  
  5.     [super viewDidLoad];  
  6.     self.obj = nil;  
  7. }  
运行,程序运行正常。说明setter 起作用了。

3、@property和@synthesize关键字 生成的代码

到底@property和@synthesize关键字生成了什么代码呢?我们自己实现getter 和setter也可以替代这些关键字。

把这两个关键字对应的代码注释掉

.h

[cpp]  view plain  copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface ViewController : UIViewController  
  4. {  
  5.     NSObject *obj;  
  6. }  
  7. //@property (nonatomic,retain) NSObject *obj;  
  8. -(NSObject*)obj;  
  9. -(void)setObj:(NSObject*)newObj;  
  10. @end  

.m

[cpp]  view plain  copy
  1. @implementation ViewController  
  2. //@synthesize obj;  
  3. - (void)viewDidLoad  
  4. {  
  5.     [super viewDidLoad];  
  6.     self.obj = nil;  
  7. }  
  8.   
  9. -(NSObject*)obj{  
  10.     return obj;  
  11. }  
  12. -(void)setObj:(NSObject*)newObj{  
  13.     if(obj != newObj){  
  14.         [obj release];  
  15.         obj = [newObj retain];  
  16.     }  
  17. }  
再运行,也能正常启动。说明自己写的getter 和setter替代了property。

4、使用三种参数的对比

@property (nonatomic,retain)NSObject *obj;

@property (nonatomic,retain,readwrite) NSObject *obj;

readwrite是默认行为,所以这两行代码等价

@property (retainNSObject *obj;

@property (atomic,retain) NSObject *obj;

atomic是默认行为,所以这两行代码是等价的。

@property(atomic,assign)int number;        

@property(atomicint number;        

@property int number;  

对int 来说,atomic assign都是默认行为,所以这三行是等价的。

@property  NSObject *obj;这样写行吗?不行的,报警告


只有int 等基础数据类型能这么写。对象必须加上赋值的类型。

@property  (retainNSObject *obj;这样就没问题了。何时使用assign、何时使用retain、copy后面再讲。

5、retaincopy实验。

使用copy。

.h文件

[cpp]  view plain  copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface ViewController : UIViewController  
  4. {  
  5.     NSString *string;  
  6. }  
  7. @property  (nonatomic, copy) NSString *string;  
  8. @end  


.m文件

[cpp]  view plain  copy
  1. @synthesize string;  
  2. - (void)viewDidLoad  
  3. {  
  4.     [super viewDidLoad];  
  5.       
  6.     NSString *str = [[NSString alloc] initWithFormat:@"abcd"];  
  7.     NSLog(@"str_Point:%p  %@  retainCount:%d", str, str, [str retainCount]);  
  8.     self.string = str;  
  9.     NSLog(@"string_Point:%p  %@  retainCount:%d", string, string, [string retainCount]);  
  10. }  
打印结果

2012-07-19 20:41:44.853 TestProject1[1213:f803] str_Point:0x6a8e0b0  abcd  retainCount:1

2012-07-19 20:41:44.854 TestProject1[1213:f803] string_Point:0x6a8e0b0  abcd  retainCount:2

内存地址是一样的,不是想其他文字所写的那样,拷贝了一份内存,这里用copy也是浅拷贝。retain也+1

使用retain

[cpp]  view plain  copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface ViewController : UIViewController  
  4. {  
  5.     NSString *string;  
  6. }  
  7. @property  (nonatomic, retain) NSString *string;  
  8. @end  
打印结果是:

2012-07-19 20:42:08.113 TestProject1[1230:f803] str_Point:0x6d3b8f0  abcd  retainCount:1

2012-07-19 20:42:08.114 TestProject1[1230:f803] string_Point:0x6d3b8f0  abcd  retainCount:2

结果和上面copy一样。


注意:在IOS5之后,加入了Automatic Reference Counting (ARC),iOS5中新加了关键字有strongweak, unsafe_unretained。

著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!


注:


因为NSString是只读的。copy正常应该是要新开辟内存的。

self.copy = copyString;
NSLog(@"%p,%@",copyString,copyString);
NSLog(@"%p,%@",self.copy,self.copy);
[copyString appendString:@"xxxx"];
NSLog(@"%p,%@",copyString,copyString);
NSLog(@"%p,%@",self.copy,self.copy);


2013-12-04 16:35:05.863 Camera[1589:a0b] 0x8e272e0,12345
2013-12-04 16:35:05.863 Camera[1589:a0b] 0x8e271f0,12345
2013-12-04 16:35:05.863 Camera[1589:a0b] 0x8e272e0,12345xxxx
2013-12-04 16:35:05.864 Camera[1589:a0b] 0x8e271f0,12345
我试了一下 看上去这里应该是mutablestring的copy才会指向一个新开辟的地址


===========================================================================


The information is now spread across several guides in the documentation. Here's a list of required reading:

The answer to this question now depends entirely on whether you're using an ARC-managed application (the modern default for new projects) or forcing manual memory management.

Assign vs. Weak - Use assign to set a property's pointer to the address of the object without retaining it or otherwise curating it; use weak to have the property point to nil automatically if the object assigned to it is deallocated. In most cases you'll want to use weak so you're not trying to access a deallocated object (illegal access of a memory address - "EXC_BAD_ACCESS") if you don't perform proper cleanup.

Retain vs. Copy - Declared properties use retain by default (so you can simply omit it altogether) and will manage the object's reference count automatically whether another object is assigned to the property or it's set to nil; Use copy to automatically send the newly-assigned object a -copymessage (which will create a copy of the passed object and assign that copy to the property instead - useful (even required) in some situations where the assigned object might be modified after being set as a property of some other object (which would mean that modification/mutation would apply to the property as well).


Copy vs Assign vs Retain

Assign is for primitive values like BOOL, NSInteger or double. For objects use retain or copy, depending on if you want to keep a reference to the original object or make a copy of it.

  • Assign

In your setter method for the property, there is a simple assignment of your instance variable to the new value,

(void)setString:(NSString*)newString{
 string = newString;
 }

This can cause problems since Objective-C objects use reference counting, and therefore by not retaining the object, there is a chance that the string could be deallocated whilst you are still using it.

  • Retain

this retains the new value in your setter method. For example: This is safer, since you explicitly state that you want to maintain a reference of the object, and you must release it before it will be deallocated.

(void)setString:(NSString*)newString{

[newString retain];

[string release];

string = newString;

}

  • Copy

this makes a copy of the string in your setter method: This is often used with strings, since making a copy of the original object ensures that it is not changed whilst you are using it.

(void)setString:(NSString*)newString{

if(string!=newString){

[string release];

string = [newString copy];

}
 }





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值