標籤:
在使用Objective-C語言進行了一段時間的iOS開發之後,發現自己的語言基礎相對薄弱,於是開始彌補自己的短處。我發現在用過一種語言之後,再回過頭來看它的很多原理會發現有更加深刻的理解。下面就對一直困惑我的屬性和成員變數的用法和關係問題進行淺析,由於水平有限可能會有錯誤,請看過文章的人多多指正。
1、屬性
關於屬性的用法在蘋果的官方文檔《The Objective-C Programming Language》中有詳細的說明,在這裡就不再贅述,連結如下:
《The Objective-c Programming Language》
如果你的英文不好,沒關係,已經有人把這個文檔全部翻譯完了,連結如下:
Objective-C程式設計語言官方文檔翻譯
2、關於@synthesize object = _object 的解釋
我們在很多代碼中會見到這樣的寫法:
[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
Objective-C的屬性和成員變數用法及關係淺析