1.關於@property
由於我們需要經常定義一些方法來訪問成員變量,因此Objective-C提供了@property指令,來爲我們自動生成setter和getter方法。
@property是編譯器指令,在Xcode4.4之後,由@property修飾的成員變量會自動生成setter和getter方法的聲明和實現。
不使用@property的情況下:
@interface Person : NSObject
{
@public
int _age;
int _number;
}
@end
@implementation Person
-(void)setAge:(int) age{
_age = age;
}
-(int)age{
return _age;
}
-(void)setNumber:(int) number{
_number = number;
}
-(int)number{
return _number;
}
@end
int main(int argc, const char * argv[]) {
Person *p = [Person new];
[p setAge:30];
NSLog(@"_number = %i, _age = %i", p->_number, p->_age);
return 0;
}
使用@property的情況:
@interface Person : NSObject
@property int age;
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
Person *p = [Person new];
[p setAge:30];
NSLog(@"_number = %i, _age = %i", p->_number, p->_age);
return 0;
}
現在:
用@property int age;就可以代替setter和getter方法的聲明和實現
注意:
(1)默認情況下,由@property生成的setter和getter方法會訪問以""開頭的成員變量,如果沒有“”開頭的成員變量,會自動生成一個以“—”開頭的成員變量,自動生成的成員變量是私有變量,只能在本來中訪問,不能在其它類中訪問。
(2)@property只會生成最簡單的getter和setter方法,而不會進行數據的處理和過濾。如果需要對數據進行判斷需要我們重寫getter/setter方法:
若重寫了setter方法,編譯器就只會生成getter方法;
若重寫了getter方法,編譯器就只會生成setter方法;
若同時重寫了setter和getter方法,編譯器就不會自動生成不存在的變量。
(3)點語法實際上就是調用成員變量的setter和getter方法,如果點語法在“等號”左邊,那麼會調用成員變量的setter方法,如果點語法在“等號”右邊,那麼會調用成員變量的getter方法。
(4)如果給一個屬性同時提供了getter/setter方法,那麼我們稱這個屬性爲可讀可寫屬性;
如果只提供了getter方法,那麼我們稱這個屬性爲只讀屬性;
如果只提供了setter方法,那麼我們稱這個屬性爲只寫屬性;
2.@property修飾符
書寫格式:
@property(屬性修飾符) 數據類型 變量名稱;
2.1權限訪問修飾符
readonly:只讀屬性,只會生成getter方法,不會生成setter方法。
readwrite:可以生成setter/getter方法,可讀可寫屬性
使用方法:
@property (readonly) int age;
2.2內存管理
assign,retain
weak,strong
這四個修飾符都是和內存管理相關的修飾符
retain和assign:
在之前的文章中我們說過,在MRC模式下,我們需要手動管理內存即手動對對象的引用計數器進行加1或減1.
例如,當進行多個對象的內存管理時,set方法需要使用
-(void)setRoom:(Room *)room{
if(_room != room){
[_room release]; //需要將之前的取值釋放掉
}
[room retain]; //當person對象使用room對象時,要對room對象的引用計數器加1
_room = room;
}
爲了方便我們開發,Objective-C爲我們提供了retain修飾符
使用方法:
@property (retain) Room *room;
總結:因此,retain只能用來修飾對象,用retain修飾過的對象會自動生成內存管理的代碼,且retain一般情況下都用在MRC模式下。
而assign剛好相反,assign只會生成普通的setter方法,並不會生成內存管理的代碼
總結:assign不會生成內存管理的代碼,不會增加引用計數,因此,assign既可以用來修飾基本類型(int float double NSInteger CGFloat,id等),也可以用來修飾對象類型。
weak和strong
在ARC(Automatical Reference Counting(自動引用計數))模式下,系統根據是否還有強指針指向當前對象判斷是否釋放當前對象。如果沒有強指針指向當前對象,則系統會釋放當前對象,如果沒有強指針指向當前對象,則當前對象就會釋放。
默認情況下,所有的指針都是強指針
例如:
{
Person *p = [[Person alloc] init];
}
//因爲p是局部變量,所以當大括號結束時,p會被回收,p回收之後,就沒有強指針指向當前對象了,所以,大括號結束的時候,Person實例對象也會被釋放。
{
__strong Person *p = [[Person alloc] init];
__weak p2 = p;
p = nil; //在這一行的時候Person實例對象會釋放
}
在ARC中進行多對象的內存管理時,需要使用strong修飾符修飾另一個對象。
@property (strong) Dog *dog;
weak修飾符和strong修飾符相對,是弱指針的意思。用弱指針指向的對象會自動釋放。
2.3 copy(深拷貝和淺拷貝)