在 .NET 體系中,static 關鍵字佔據核心地位——靜態方法與屬性無需實例化即可直接呼叫。Objective-C 同樣擁有 static 關鍵字,但其行為與 C# 有顯著差異。本文將系統梳理 Objective-C 中靜態變數的作用域、靜態屬性的正確宣告位置、以及類方法(靜態方法)的定義方式,並附上完整程式碼示例與執行結果驗證。
在 Objective-C 中,於 .m 實作檔案頂層宣告的 static 變數,其作用域僅限於該編譯單元。其他類別無法透過類別名稱直接存取,必須透過該類別提供的方法間接修改。這體現了封裝性:靜態變數實際上是「檔案級私有」。
@interface Person : NSObject {
int age;
NSString *name;
static int totalCount; // 編譯錯誤:不允許在介面區塊宣告 static 實例變數
}
@property int age;
@property NSString *name;
-(void) write;
+(void) hello;
@end
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject {
int age;
NSString *name;
}
@property int age;
@property NSString *name;
-(void) write;
+(void) hello;
@end
// Person.m
#import "Person.h"
static int count; // 檔案級靜態變數
@implementation Person
@synthesize age;
@synthesize name;
-(void) write {
NSLog(@"姓名:%@ 年齡:%i", name, age);
}
+(void) hello {
count++;
NSLog(@"static = %i", count);
}
@end
@autoreleasepool {
for (int i = 0; i < 5; i++) {
[Person hello];
}
}
輸出:
2014-02-15 22:03:14.642 static = 1
2014-02-15 22:03:14.644 static = 2
2014-02-15 22:03:14.644 static = 3
2014-02-15 22:03:14.645 static = 4
2014-02-15 22:03:14.645 static = 5
觀察可知:[Person hello] 直接以類別名稱呼叫類方法,且 count 於每次呼叫遞增,證明其為類級別共享狀態。
+(void) hello {
static int count; // 函式級靜態變數,同樣屬於類全域
count++;
NSLog(@"static = %i", count);
}
效果與檔案頂層宣告完全一致,因為 Objective-C 的類方法本質上是類物件的實例方法,函式靜態變數在所有呼叫間共享。
-(void) write {
static int myage = 0; // 函式級靜態變數
myage++;
NSLog(@"年齡:%i", myage);
}
@autoreleasepool {
for (int i = 0; i < 5; i++) {
Person *p = [[Person alloc] init];
p.name = [NSString stringWithFormat:@"object c %d", i];
[p write];
}
}
輸出:
姓名: object c 0 年齡:1
姓名: object c 1 年齡:2
姓名: object c 2 年齡:3
姓名: object c 3 年齡:4
姓名: object c 4 年齡:5
關鍵現象:雖然迴圈中每次 alloc/init 產生全新實例,name 隨著改變,但 myage 保留上一次執行結果並持續遞增。這正是 static 在函式內部的核心語義——生命週期贯穿整個程式執行,但可見性僅限於該函式。
Objective-C 不使用 static 關鍵字修飾方法,而是以 + 號取代 - 號:
// 介面宣告
+(void) hello;
// 實作
+(void) hello {
// 實作內容
}
呼叫方式:[ClassName methodName],無需實例化。這與 C# 的 static void Method() 對應,但語法風格截然不同。
static 於 .m 檔頂層或方法內部,作用域為檔案級或函式級,不可於 @interface 區塊宣告。+ 開頭定義,對應 C# static 方法,透過類別名稱直接呼叫。static 變數:所有實例共享同一儲存空間,適合做計數器、快取等跨實例狀態。掌握這些細節,能避免從 C#/.NET 轉型時的常見誤區,編寫更地道的 Objective-C 程式碼。