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

Objective-C 類成員變量與屬性詳解:_ivar vs @property 核心區別與最佳實踐

     編輯:關於C語言

Objective-C 類成員變量與屬性詳解:_ivar vs @property 核心區別與最佳實踐

Objective-C 中「成員變量(Instance Variable,ivar)」與「屬性」是初學者最易混淆的概念。本文通過實例代碼演示,得出核心結論:類內部使用成員變量({} 中聲明),類外部使用屬性(@property),並詳細講解訪問控制、手動 Getter/Setter、@synthesize 自動合成、現代 Runtime 自動合成的演進。

一、成員變量基礎

// People.h
@interface People : NSObject {
    NSString *_peopleName;  // 默認 @protected
}
// @public 可改為公開,但不推薦
@end
  • 訪問語法:obj->ivar(需 @public 或同類/子類內部)。
  • 默認 @protected:僅當前類與子類可見。
  • 不推薦類外直接訪問 ivar,破壞封裝,且無法攔截讀寫(KVO、副作用)。

二、類內部使用 ivar:初始化與自定義 Getter/Setter

// People.m
@implementation People
- (instancetype)init {
    self = [super init];
    if (self) {
        _peopleName = @"people name 1"; // 直接賦值 ivar
    }
    return self;
}
- (NSString *)getName { return _peopleName; }
- (void)setName:(NSString *)name { _peopleName = name; }
@end

類內部直接操作 _ivar 高效且無副作用,是標準做法。

三、屬性:類外部的標準介面

1. 聲明與屬性修飾符

@property (nonatomic, strong) NSString *peopleName;
// nonatomic: 非原子操作,多線程不加鎖,性能高
// strong: 強引用(ARC 下相當於 retain),對象持有期管理

2. @synthesize 手動合成(舊版本必要)

@implementation People
@synthesize peopleName = _peopleName; // 將屬性 peopleName 映射到 ivar _peopleName
// 自動生成 getter/setter:
// - (NSString *)peopleName { return _peopleName; }
// - (void)setPeopleName:(NSString *)name { _peopleName = name; }
@end
  • 下劃線 _ 關鍵:區分屬性名與 ivar 名,避免無限遞歸。
  • 現代 Xcode (LLVM 4.0+) 默認自動合成,無需寫 @synthesize,編譯器自動生成 _propertyName ivar 及存取方法。

3. 類外部調用屬性

People *p = [[People alloc] init];
NSLog(@"%@", p.peopleName);   // 呼叫 getter
p.peopleName = @"new name";   // 呼叫 setter

點語法 p.peopleName 編譯器自動轉為 [p peopleName] / [p setPeopleName:]。

四、現代最佳實踐總結

五、常見誤區

  1. 以為 @property 必須配合 @synthesize:現代編譯器自動合成,手寫反而易出錯(如忘寫下劃線)。
  2. 類外用 obj->_ivar:破壞封裝,繞過 setter 內存管理,極易崩潰。
  3. 混淆 nonatomic/atomic:atomic 只保證存取器原子性,不保證線程安全邏輯,性能開銷大,非必要用 nonatomic。

六、總結

「類內用 ivar,類外用 property」是 Objective-C 封裝設計的黃金法則。理解 ivar 與 property 的映射關係、自動合成機制、訪問控制語義,能寫出既高效又安全的現代 Objective-C 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景推薦做法原因
.h 介面聲明只寫 @property,不寫 {} ivar編譯器自動生成私有 ivar,介面乾淨
.m 實現初始化直接用 _propertyName 賦值繞過 setter 副作用,效率高
類內部邏輯讀寫優先用 _ivar,需觸發 KVO/副作用時用 self.property區分「內部狀態變更」與「公開介面契約」
類外部訪問只用 self.property / obj.property享受封裝、KVO、內存管理、線程安全(atomic)