首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C @property 深度解析:從聲明到實現、屬性修飾符與記憶體管理

     編輯:關於C語言

為什麼需要 @property?

在早期 Objective-C 中,為每個實例變數手寫 setter/getter 既繁瑣又易出錯:

// 手動聲明
- (void)setRainHandling:(float)rainHandling;
- (float)rainHandling;
- (void)setSnowHandling:(float)snowHandling;
- (float)snowHandling;

@property 編譯指令自動生成 setter/getter 聲明,將上述四行簡化為:

@property float rainHandling;
@property float snowHandling;

@synthesize:自動實現存取方法

聲明僅是介面,實現靠 @synthesize:

@synthesize rainHandling;
@synthesize snowHandling;

編譯器會自動生成標準的存取方法實現,並自動創建同名實例變數(若未手動聲明)。Xcode 4.5+ 起甚至可省略 @synthesize,完全由編譯器自動處理。

屬性修飾符:控制記憶體語義與線程安全

修飾符語義適用場景
assign簡單賦值,不保留基本資料型別(int, float)、delegate 弱引用
retain保留新值,釋放舊值MRC 環境下的物件屬性
copy複製新物件,與原物件獨立NSString, NSArray, NSDictionary 等可變類別的不可變對應類
strongARC 環境下等同 retainARC 專案的物件屬性(預設)
weak弱引用,物件釋放自動置 nilDelegate、避免循環引用
readonly僅生成 getter計算屬性、不可變狀態
readwrite生成 setter 與 getter(預設)可讀寫屬性
nonatomic非原子操作,不加鎖,效率高單線程訪問、效能敏感場景(iOS 開發常用)
atomic原子操作,線程安全(預設)多線程共享屬性(有效能開銷)

點語法:存取方法的語法糖

// 等價於 [obj setRainHandling:0.5];
obj.rainHandling = 0.5;  

// 等價於 [obj rainHandling];
float value = obj.rainHandling;

點表達式本質仍是呼叫 setter/getter,非直接訪問實例變數。左值調用 setter,右值調用 getter。

自定義實例變數名稱

@interface AllWeatherTire : Tire {
    NSString *tireName;  // 實例變數名不同
}
@property (copy) NSString *name; // 公開屬性名
@end

@implementation AllWeatherTire
@synthesize name = tireName; // 映射關係
// 內部必須用 self.name = @"Car",不能直接用 name = @"Car"
@end

@dynamic:告訴編譯器「我自己搞定」


@property (readonly) float bodyMassIndex;
@dynamic bodyMassIndex; // 不生成實例變數、不生成存取方法

- (float)bodyMassIndex {
    return self.weight / (self.height * self.height); // 動態計算
}

若調用不存在的 setter/getter 會崩潰。適用於 Core Data 托管屬性、動態代理等場景。

屬性的局限性

屬性僅支援單參數 setter/getter,無法處理帶額外參數的方法,例如:


- (void)setTire:(Tire *)tire atIndex:(int)index;
- (Tire *)tireAtIndex:(int)index;

此類場景仍需手動實現方法。

總結

  • @property:聲明屬性特徵(類型、記憶體語義、線程安全)
  • @synthesize:請求編譯器生成標準實現與實例變數
  • @dynamic:完全手動實現,編譯器不介入
  • 點語法:調用存取方法的便捷寫法
  • 善用 copy 防御可變物件副作用,weak 打破循環引用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved