在使用Objective-C語言進行了一段時間的iOS開發以後,發現本身的語言基礎相對薄弱,因而開始彌補本身的短處。我發如今用過一種語言以後,再回過頭來看它的不少原理會發現有更加深入的理解。下面就對一直困惑個人屬性和成員變量的用法和關係問題進行淺析,因爲水平有限可能會有錯誤,請看過文章的人多多指正。html
一、屬性編程
關於屬性的用法在蘋果的官方文檔《The Objective-C Programming Language》中有詳細的說明,在這裏就再也不贅述,連接以下:app
《The Objective-c Programming Language》編程語言
若是你的英文很差,不要緊,已經有人把這個文檔所有翻譯完了,連接以下:函數
二、關於@synthesize object = _object 的解釋spa
咱們在不少代碼中會見到這樣的寫法:.net
[plain] view plaincopy翻譯
@interface MyClass:NSObject{ 指針
MyObjecct *_object;
}
@property(nonamtic, retain) MyObjecct *object;
@end
@implementatin MyClass
@synthesize object=_object;
我在網上查閱了一些和其餘人寫的博文,總結了這樣寫的幾條緣由以下:
(1)32位系統和64位系統的差別
在32位系統中,若是類的@interface部分沒有進行ivar(instance variable)聲明,但有@property聲明,在類的@implementation部分有響應的@synthesize,則會獲得相似下面的編譯錯誤:
Synthesize property ‘xX’ must either be named the same as a compatible ivar or must explicitly name an ivar
在64位系統中,運行時系統會自動給類添加ivar,添加的ivar以一個下劃線「_」作前綴。
(2)避免莫名其妙的Bug
在這裏簡單說一下_object和object的區別。_object是MyClass類的成員變量,object是屬性。property和synthesize定義了一對getter和setter方法,在這裏的getter方法是object,setter方法是setObject,事實上getter和setter方法操做的是變量_object。
若是寫synthesize objec = _object 時getter方法爲:
[plain] view plaincopy
-(MyObject *)object
{
return _object;
}
若是寫synthesize object 時getter方法爲:
[plain] view plaincopy
-(MyObject *)object
{
return object;
}
當函數名和屬性名重名的時候會出現意想不到的錯誤,爲了不這種Bug,Apple給的Demo Code裏面多數也採用這種方式。
(3)屬性和變量的用法
屬性是用self.object,經過getter方法來調用的,能夠在類外使用。而變量是經過_object來調用,只能在該類對應的implementation中使用,在類外不能使用。
下面看一下兩種賦值操做:
[plain] view plaincopy
self.object = [[MyObject alloc] init];
object = [[MyObject alloc] init];
第一種的方式和@property(nonamtic,retain)有關,其實是經過調用setter方法setObject來實現賦值的。第二種方式是簡單的指針賦值,沒有調用setter方法。
下面是retainCount的變化:
[plain] view plaincopy
MyObject *tmp = [[MyObject alloc] init];
self.object = tmp; //retainCount = 2
[tmp release]; //retainCount = 1
_object = [[MyObject alloc] init]; //retainCount = 1