黑馬程序員――@property及其參數的詳解
來源:程序員人生 發布時間:2015-08-12 08:28:50 閱讀次數:3874次
------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交換! ------
@property詳解
1.甚么是@property?
@property是OC獨有的1個關鍵字,它屬于編譯器1個特性,編譯器碰到@property時,會自動展開為成員變量的set和get方法
在Xcode4.5之前,Xcode編譯器碰到@property會將其轉換為成員變量set、get方法的聲明,碰到@synthesize會展開為成員變量set、get方法的實現,所以XCode4.5之前,@property與@synthesize是配對使用。在Xcode4.5以后,Xcode碰到@property關鍵字,其將自動幫我們轉換為(成員變量的聲明、相應set、get方法的聲明與實現)。
2.我們怎樣使用@property?
代碼解釋:
我們手動寫的代碼(關閉ARC機制):
@interface Person : NSObject
{
NSString *_name;
}
- (void) setName:(NSString *)name;
- (NSString *) name;
@end
@implementation Person
-(void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name retain];
}
}
-(NSString *)name
{
return _name;
}
-(void)dealloc
{
[_name release];
[super dealloc];
}
@end
Xcode4.5之前,利用@property與@synthesize配對寫的代碼
//Xcode 4.5以下的寫法
@interface Person :NSObject
@property NSString *name;
/*
*@property NSString *name;這句展開為:
*{
* NSString *_name;
*}
*- (void) setName:(NSString *)name;
*- (NSString *) name;
*/
@end
@implementation Person
@synthesize name = _name;//這里必須要寫 =_name,否則展開的代碼會自動創建1個私有變量:NSString *name;(其他類不可訪問(包括子類))
/*@synthesize name = _name;這句展開以下:(展開的是不符合內存管理的)
*-(void)setName:(NSString *)name
*{
* _name = name;
*}
*-(NSString *)name
*{
* return _name;
*}
*/
@end
Xcode 4.5以后的寫法,只用關鍵字@property:
#import <Foundation/Foundation.h>
//Xcode 4.5以上的寫法
@interface Person : NSObject
@property NSString *name;
/*
*@property NSString *name;這句在@interface中展開有:
*{
* NSString *_name;
*}
*- (void) setName:(NSString *)name;
*- (NSString *) name;
*
*@property NSString *name;這句在@implementation中展開有:
*
*-(void)setName:(NSString *)name
*{
* _name = name;
*}
*-(NSString *)name
*{
* return _name;
*}
*/
@end
@implementation Person
//Xcode4.5往后,都不用寫@synthesize
@end
@propert的相干參數
1.@property有哪些參數?
第1組:retain assign copy strong weak unsafe_unretained autoreleasing
第2組:readwrite readonly
第3組:nonatomic atomic
第4組:setter getter
2.參數分別有何作用?
①參數說明
第1組(retain assign copy strong weak unsafe_unretained autoreleasing)用于:set方法內存管理
assign(默許參數):生成直接賦值的set方法(不斟酌內存管理),適用于非OC對象(基本數據類型、復合數據類型)
retain:生成符合內存管理的set方法(release舊值,retain新值),適用于OC對象的成員變量
copy:生成符合內存管理的set方法(release舊值,copy新值),適用于NSString、NSArray等不可變對象。
Strong:強援用,決定了對象的存亡(1個對象如果沒有強指針指向(援用計數器為0)時,對象將被燒毀,釋放內存),其指向1個對象,相當于該對象做了1次retain操作。適用于OC對象
weak:弱援用,其存在與否無所謂(弱指針指向對象與否(對象援用計算器不變)),適用于OC對象
unsafe_unretained:請查看:浪天涯的博客
注意:
weak與Strong1般在開啟ARC機制下使用
Strong:強援用,決定了對象的存亡(1個對象如果沒有強指針指向(援用計數器為0)時,對象將被燒毀,釋放內存),其指向1個對象,相當于該對象做了1次retain操作。
非ARC的retain,相當于ARC的strong,弱援用相當于assign
使用copy參數與使用retain參數產生的set方法1致(將生成set方法中的retain改成copy便可)
第2組(readwrite readonly)用于:是不是要生成set方法
readwrite(默許參數):同時生成set、get方法的聲明與實現
readonly:只生成get方法的聲明與實現(不生成set的方法的聲明與實現)
第3組(nonatomic atomic)用于:多線程管理
atomic(默許參數):原子性,性能低(1般開發OC中的APP不推薦使用,做金融等高安全的時候使用)
nonatomic:非原子性,性能高(強烈推薦使用,性能高)
atomic:(原子性操作)就是1個操作履行進程不能被中斷, 要不就履行完, 要不就不履行(1個操作不可以被中途cpu暫停然后調度)。如果1個操作是原子性的,
那末在多線程環境下, 就不會出現變量被修改等奇怪的問題(保證數據同步)。原子操作就是不可再分的操作,在多線程程序中原子操作是1個非常重要的概念,它常經常使用來實現1些同步機制,同時也是1些常見的多線程Bug的源頭。
nonatomic:(非原子性操作)操作是直接從內存中取數值(不斟酌其是不是被占用),由于它是從內存中獲得數據,它并沒有1個加鎖的保護來用于cpu中的寄存器計算Value,它只是單純的從內存地址中,當前的內存存儲的數據結果來進行使用。在多線程環境下可提高性能,但沒法保證數據同步。
第4組(setter getter)用于:set、get方法重命名(經常使用于BOOL類型的成員變量的get方法,BOOL方法常以is開頭(set方法很少用))
setter:給成員變量的set方法重命名,set方法默許命名:- (void) set成員變量名(成員變量名首字母大寫):(成員變量數據類型)成員變量名
getter:給成員變量的set方法重命名,get方法默許命名:- (成員變量數據類型) 成員變量名
②代碼證明
參數實例示范:
main.m文件
/*
*第1組:retain assign copy strong weak
*第2組:readwrite readonly
*第3組:nonatomic atomic
*第4組:setter getter
*/
#import <Foundation/Foundation.h>
#import "Student.h"
#import "Book.h"
int main(int argc, const char * argv[]) {
Student *stu = [[Student alloc]init];
Book *b = [[Book alloc]init];
Book *b1 = [[Book alloc]init];
/*******驗證retain與assign********/
NSLog(@"b = %ld",[b retainCount]);
NSLog(@"b1 = %ld",[b1 retainCount]);
stu.book = b;
stu.book1 = b1;
NSLog(@"book(參數:retain)使用后b = %ld",[b retainCount]);
NSLog(@"book1(參數:assign)使用后b1 = %ld",[b1 retainCount]);
/***********驗證readonly*****************/
//stu.age = 10;調用setAge方法報錯,setAge方法不存在,說明沒有生成setAge方法
//可以輸出stu中age的值,說明生成了get方法
NSLog(@"Student age is %i",stu.age);
/***********驗證setter與getter****************/
//可以調用stu的isMan方法,而我們又沒有寫setIsMan方法,說明重命名成功
stu.isMan = YES;
NSLog(@"%d",stu.isMan);
[b1 release];
[b release];
[stu release];
return 0;
}
Student.h文件
/*在非ARC(關閉ARC)下驗證:
*第1組:retain assign copy strong weak
*第2組:readwrite readonly
*第3組:nonatomic atomic
*第4組:setter getter
*/
#import <Foundation/Foundation.h>
@class Book;
@interface Student : NSObject
/***********驗證retain*************/
@property (nonatomic,retain,readwrite) Book *book;
/*以上使用retain參數,展開的set實現方法為:
*- (void) setBook:(Book *)book
*{
* if(_book != book)
* {
* [_book release];
* _book = [book retain];
* }
*}
**/
/***********驗證assign*************/
@property (nonatomic,assign,readwrite) Book *book1;
/*以上使用retain參數,展開的set實現方法為:
*- (void) setBook:(Book *)book
*{
* _book = book;
*}
**/
/***********驗證readonly*************/
@property (nonatomic,assign,readonly) int age;
/*以上使用readonly參數,只生成get方法:
*- (int) age;
*{
* return _age;
*}
**/
/***********驗證setter與getter*************/
@property (nonatomic,assign,readwrite,setter=setIsMan:,getter=isMan) BOOL man;
/*以上使用setter參數,只生成set方法名被修改成:isMan
*- (void) isMan:(BOOL)man;(默許方法名為:man)
*{
* _man = man;
*}
*
*以上使用getter參數,只生成get方法名被修改成:isMan
*- (BOOL) isMan;(默許方法名為:man)
*{
* return _man;
*}
**/
@end
Student.m文件
#import "Student.h"
#import "Book.h"
@implementation Student
-(void)dealloc
{
[_book release];
NSLog(@"Student被燒毀??!");
[super dealloc];
}
@end
Book.h文件
#import <Foundation/Foundation.h>
@interface Book : NSObject
@property (nonatomic,copy,readwrite) NSString *name;
@end
Book.m文件
#import "Book.h"
@implementation Book
-(void)dealloc
{
[_name release];
NSLog(@"book被燒毀!!");
[super dealloc];
}
@end
參數結果輸出:
2015-05-01 12:02:53.108 07-@property及其參數[2364:221860] b = 1
2015-05-01 12:02:53.109 07-@property及其參數[2364:221860] b1 = 1
2015-05-01 12:02:53.109 07-@property及其參數[2364:221860] book(參數:retain)使用后b = 2
2015-05-01 12:02:53.110 07-@property及其參數[2364:221860] book1(參數:assign)使用后b1 = 1
2015-05-01 12:02:53.110 07-@property及其參數[2364:221860] Student age is 0
2015-05-01 12:02:53.110 07-@property及其參數[2364:221860] 1
2015-05-01 12:02:53.110 07-@property及其參數[2364:221860] book被燒毀!!
2015-05-01 12:02:53.110 07-@property及其參數[2364:221860] book被燒毀!!
2015-05-01 12:02:53.110 07-@property及其參數[2364:221860] Student被燒毀?。?/div>
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
------分隔線----------------------------
------分隔線----------------------------