@property是什么
@Property是聲明屬性的語法,它可以快速方便的為實(shí)例變量創(chuàng)建存取器,并允許我們通過點(diǎn)語法使用存取器。
存取器(accessor):指用于獲取和設(shè)置實(shí)例變量的方法。用于獲取實(shí)例變量值的存取器是getter,用于設(shè)置實(shí)例變量值的存取器是setter。
創(chuàng)建存取器
手工創(chuàng)建存取器
我們先看兩段代碼:
//Fraction.h
#import <Foundation/Foundation.h>
@interface Fraction:NSObject
{
int numerator;
int denominator;
}
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(int) numerator;
-(int) denominator;
-(double) convertToNum;
上面代碼中numerator、denominator是Fraction類的實(shí)例變量,并且看到對(duì)這兩個(gè)實(shí)例變量都聲明了set/get方法。
//Fraction.m
#import "Fraction.h"
@implementation Fraction
-(void) print
{
NSlog (@"%i/%i", numerator, denominator);
}
-(void) setNumerator: (int) n
{
numerator=n;
}
-(void) setDenominator: (int) d
{
denominator=d;
}
-(int) numerator
{
return numerator;
}
-(int) denominator
{
return denominator;
}
-(double) convertToNum
{
if (denominator != 0)
return (double) numerator / denominator;
else
return 1.0;
}
@end
上面代碼是對(duì)實(shí)例變量存取器的實(shí)現(xiàn)。我們可以看到,存取器就是對(duì)實(shí)例變量進(jìn)行賦值和取值。按照約定賦值方法以set開頭,取值方法以實(shí)例變量名命名。
使用@Property創(chuàng)建存儲(chǔ)器
@interface Fraction:NSObject
{
int numerator;
int denominator;
}
@property int numerator, denominator;
-(void) print;
-(double) convertToNum;
上面代碼中,我們使用@property聲明兩個(gè)屬性,名稱與實(shí)例變量名稱相同。
@implementation Fraction
@synthesize numerator, denominator;
-(void) print
{
NSlog (@"%i/%i", numerator, denominator);
}
-(double) convertToNum
{
if (denominator != 0)
return (double) numerator / denominator;
else
return 1.0;
}
@end
和手動(dòng)生成存取器相比,在.m文件中我們使用@synthesize自動(dòng)生成這兩個(gè)實(shí)例變量的存取器,并且隱藏了存取器,雖然我們看不到存取器,但它們確實(shí)是存在的。
總結(jié):
@property等同于在.h文件中聲明實(shí)例變量的get/set方法,@synthesize等同于在.m文件中實(shí)現(xiàn)實(shí)例變量的get/set方法。使用@property和synthesize創(chuàng)建存取器要比手動(dòng)聲明兩個(gè)存取方法(getter和setter)更簡單。而且我們?cè)谑褂脤傩詴r(shí)可以使用點(diǎn)語法賦值或取值,語法更簡單,更符合面向?qū)ο缶幊獭?/p>
不必單獨(dú)聲明實(shí)例變量
如果我們希望使用默認(rèn)的實(shí)例變量命名方式,那么我們?cè)?m文件中就不需要使用@synthesize聲明,系統(tǒng)會(huì)幫我們自動(dòng)完成(以“_實(shí)例變量名字”來命名)。
@synthesize numerator = _numerator;
@synthesize denominator = _denominator;
如果我們希望自己命名實(shí)例變量命,那么我們就使用@synthesize顯示聲明我們希望的實(shí)例變量名。
@property的特性
@property還有一些關(guān)鍵字,它們都是有特殊作用的,比如上述代碼中的nonatomic,strong。
把它們分為三類,分別是:原子性,存取器控制,內(nèi)存管理。
原子性
atomic(默認(rèn)):atomic意為操作是原子的,意味著只有一個(gè)線程訪問實(shí)例變量。atomic是線程安全的,至少在當(dāng)前的存取器上是安全的。它是一個(gè)默認(rèn)的特性,但是很少使用,因?yàn)楸容^影響效率,這跟ARM平臺(tái)和內(nèi)部鎖機(jī)制有關(guān)。
nonatomic:nonatomic跟atomic剛好相反。表示非原子的,可以被多個(gè)線程訪問。它的效率比atomic快。但不能保證在多線程環(huán)境下的安全性,在單線程和明確只有一個(gè)線程訪問的情況下廣泛使用。
存取器的控制
readwrite(默認(rèn)):readwrite是默認(rèn)值,表示該屬性同時(shí)擁有setter和getter。
readonly: readonly表示只有g(shù)etter沒有setter。
內(nèi)存管理
主要涉及到assign、retain、strong、weak、copy等情況,以及各自的使用場(chǎng)景。
Strong:強(qiáng)引用,表示實(shí)例對(duì)象對(duì)傳入的對(duì)象有所有權(quán)關(guān)系。常用在:自定義對(duì)象,控制器對(duì)象。
Weak:弱引用,在setter方法中,需要對(duì)傳入的對(duì)象不進(jìn)行引用計(jì)數(shù)加1的操作,也就是,對(duì)傳入的對(duì)象沒有所有權(quán),當(dāng)該對(duì)象的引用計(jì)數(shù)為0時(shí),該對(duì)象即被釋放,用weak聲明的實(shí)例變量指向nil,即實(shí)例變量的值為0。常用在:delegate對(duì)象,IBOutLet。
Assign:簡單賦值,不改變引用計(jì)數(shù),適合簡單數(shù)據(jù)類型如NSInteger、CGFloat、int、float等。
Copy:把原來的對(duì)象完整復(fù)制另外一個(gè)地方,重新加載內(nèi)存區(qū),原來對(duì)象變了不影響新內(nèi)存區(qū)的對(duì)象。常用在:NSString、NSArray、NSDictionary及其子類等。