iOS學習筆記1(結合專案)---oc的@property屬性

jingxianli0922發表於2015-10-26

“屬性”(property)有兩大概念:ivar(例項變數)、存取方法(access method=getter),即@property = ivar + getter + setter。

例如下面的這個類:

@interface WBTextView :UITextView
@property (nonatomic,copy)NSString *placehold;
@property (nonatomic,copy)UIColor *placeholdColor;
@end

類完成屬性的定以後,編譯器會自動編寫訪問這些屬性的方法(自動合成autosynthesis),上述程式碼寫出來的類等效與下面的程式碼:

@interface WBTextView :UITextView
- (NSString *)placehold;
-(void)setPlacehold:(NSString *)placehold;
-(UIColor *)placeholdColor;
-(void)setPlaceholdColor:(UIColor *)placeholdColor;
@end

大家可能會想,編譯器是如何實現該功能。原理如下

1)OBJC_IVAR_$類名$屬性名稱 :該屬性的“偏移量” (offset),這個偏移量是“硬編碼” (hardcode),表示

該變數距離存放物件的記憶體區域的起始地址有多遠。

2)setter與getter方法對應的實現函式

3)ivar_list :成員變數列表

4)method_list :方法列表

5)prop_list :屬性列表

也就是說我們每次在增加一個屬性,系統都會在ivar_list中新增一個成員變數的描述,在method_list中

增加setter與getter方法的描述,在屬性列表中增加一個屬性的描述,然後計算該屬性在物件中的偏移量,

然後給出setter與getter方法對應的實現,在setter方法中從偏移量的位置開始賦值,在getter方法中從

偏移量開始取值,為了能夠讀取正確位元組數,系統物件偏移量的指標型別進行了型別強轉.

雖說系統自帶的自動合成(autosynthesis)給我們帶來很多方便,但有時一不小心就有可能導致錯誤。

@import Foundation;
@interface WBTextView :UITextView
@property (nonatomic,copy)NSString *placehold;
@end

-(instancetype)init
{
 self = [superinitWithFrame:frame];
    if (self) {
            _placeholde = @"jasonjwl";
    }
    returnself;
}

-(NSString *)placehold
{
    return _placehold;
}

-(void)setPlacehold:(NSString *)placehold
{
    _placehold = [placehold copy];
}
上面的程式碼不能通過編譯,因為當你同時重寫setter和getter時,系統不會生成ivar變數。

那什麼情況下,不會autosynthesis?

1.同時重寫了setter和getter時重寫了只讀屬性的getter時
2.使用了@dynamic時
3.在 @protocol 中定義的所有屬性
4.在 category 中定義的所有屬性
5.過載的屬性

感謝程式猿的提供招聘一個靠譜的 iOS》—參考答案(上)


相關文章