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

Objective-C 類別建構完整實戰:介面宣告、實作、屬性與記憶體管理

     編輯:關於C語言

一、類別定義三部曲

1. 介面檔

// TestClass.h
#import 

@interface TestClass : NSObject

// 公開屬性 (自動合成 _ivar + getter/setter)
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *tag; // copy 防御可變字串

// 公開方法
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
- (void)greet;
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age; // 便利建構器

@end

2. 實作檔

// TestClass.m
#import "TestClass.h"

@implementation TestClass

// 指定初始化器
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age {
    if (self = [super init]) {
        _name = [name copy]; // 手動 copy (屬性已 copy 自動處理)
        _age = age;
        _tag = @"default";
    }
    return self;
}

// 便利建構器
+ (instancetype)personWithName:(NSString *)name age:(NSInteger)age {
    return [[self alloc] initWithName:name age:age]; // 用 self 支援子類別
}

- (void)greet {
    NSLog(@"Hello, I'm %@, %ld years old. Tag: %@", _name, (long)_age, _tag);
}

@end

3. 使用範例

// main.m
#import 
#import "TestClass.h"

int main(int argc, const char *argv[]) {
    @autoreleasepool {
        // 1. alloc/init
        TestClass *p1 = [[TestClass alloc] initWithName:@"Alice" age:25];
        [p1 greet];
        
        // 2. 便利建構器
        TestClass *p2 = [TestClass personWithName:@"Bob" age:30];
        [p2 greet];
        
        // 3. 屬性存取 (點語法 = 呼叫 getter/setter)
        p1.age = 26;
        p1.tag = @"VIP";
        NSLog(@"Updated: %@, %ld, %@", p1.name, (long)p1.age, p1.tag);
        
        // 4. 直接存取 ivar (不推薦,繞過 KVO/屬性觀察)
        // p1->_age = 99; // 只在 init/dealloc/自定義 setter 內使用
    }
    return 0;
}

二、屬性修飾語完整對照表

屬性關鍵字效果適用場景
原子性atomic (預設)getter/setter 加鎖,執行緒安全多執行緒共享、簡單型別
nonatomic無鎖,高效能絕大多數情況、UI 物件、單執行緒
記憶體語意strong (預設)保持強參考,ARC 管理物件擁有關係
weak不保持,物件釋放自動置 nil代理、父視圖、打破循環保留
copysetter 執行 copy,新物件 count=1NSString, NSArray, NSDictionary, Block
assign單純賦值,不影響計數基本型別、CGRect、非 OC 物件、MRC delegate
unsafe_unretained像 weak 但不自動置 nil極少用,需確定生命週期
讀寫權限readwrite (預設)生成 getter + setter可讀可寫
readonly僅生成 getter不可變屬性、計算屬性
自定義存取getter=xxx, setter=xxx改變方法名布林屬性 getter=isEnabled
空值重設null_resettableset nil 時重設為預設值iOS 11+、配合 NS_DESIGNATED_INITIALIZER

三、關鍵設計模式

指定初始化器模式

  • 類別指定一個 initWith… 為指定初始化器,完整初始化所有 ivar。
  • 其他 init 方法呼叫指定初始化器。
  • 子類別覆寫指定初始化器時必須呼叫 [super designatedInit]。
  • 標記 NS_DESIGNATED_INITIALIZER 讓編譯器檢查。

便利建構器模式

  • 類別方法 + typeWith…。
  • 內部呼叫 [[self alloc] initDesignated…]。
  • 回傳 instancetype。
  • ARC 下無需 autorelease。

不可變/可變對應模式

// 不可變介面
@interface ImmutableData : NSObject
@property (readonly, copy) NSString *content;
- (instancetype)initWithContent:(NSString *)c;
@end

// 可變子類別
@interface MutableData : ImmutableData
@property (readwrite, copy) NSString *content; // 重新宣告為 readwrite
- (void)appendString:(NSString *)s;
@end

四、記憶體管理實戰檢查清單

  1. 所有物件屬性預設 strong (ARC) / retain (MRC)。
  2. 代理、Block 捕獲 self、父視圖 → weak。
  3. NSString/NSArray/NSDictionary/Block → copy。
  4. 基本型別、結構體、Core Foundation → assign。
  5. dealloc 僅釋放非 ARC 管理資源 (如 CFRelease、free、移除通知觀察者),不呼叫 [super dealloc] (ARC 禁止)。
  6. 單例:static id _instance; + (id)shared { static dispatch_once_t once; dispatch_once(&once, ^{ _instance = [[self alloc] init]; }); return _instance; }

五、現代 Objective-C 最佳實踐 (LLVM/Clang)

  • 實例變數自動合成 _propertyName,無需手動 @synthesize。
  • 方法回傳型別用 instancetype 而非 id。
  • 常量字串用 @"...",格式化 [NSString stringWithFormat:]。
  • 區塊 (Block) 類型定義:typedef void(^CompletionBlock)(BOOL success, NSError *error);。
  • 泛型集合 (Xcode 7+):NSArray *names; 編譯期型別檢查。
  • 空值檢查:if (obj) { ... } 而非 if (obj != nil)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved