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

Objective-C 對象創建、self、super 深度解析:隱藏參數、消息發送、初始化鏈

     編輯:關於C語言

核心概念

  • self:隱藏參數,指向當前消息接收者(調用方法的對象)
  • _cmd:隱藏參數,當前方法的 Selector (SEL)
  • super:非參數,編譯器指示符,指示「從父類開始查找方法實現」
  • self 和 super 指向同一個對象,唯一區別在方法查找起點

消息發送機制

調用方式方法查找起點典型用途
[self method]當前類 → 父類 → ... → NSObject正常調用,支持多態
[super method]父類 → 祖父類 → ... → NSObject調用父類實現,通常在重寫方法中

完整示例:Person 與 Student

Person.h


#import 
@class Student; // 前向聲明,減少頭文件依賴

@interface Person : NSObject {
    int age;
    NSString *name;
    Student *student;
}
- (NSString *)getName;
- (void)setName:(NSString *)name;
- (int)getAge;
- (void)setAge:(int)age;
@end

Person.m


#import "Person.h"
#import "Student.h" // 實現文件引入完整定義

@implementation Person
- (id)init {
    if (self = [super init]) { // 必須調用父類初始化
        student = [[Student alloc] init];
        NSLog(@"student: %@", student);
    }
    return self;
}

- (void)setName:(NSString *)name {
    _name = name;
    [self setAge:14]; // self 調用本類方法(多態入口)
    NSLog(@"setAge called");
    NSLog(@"self class: %@", [self class]);      // 實際類型
    NSLog(@"super class: %@", [super superclass]); // 父類類型
}

- (NSString *)getName { return _name; }
- (int)getAge { return _age; }
- (void)setAge:(int)age { _age = age; }
@end

關鍵場景解析

1. 初始化鏈中的 super


- (id)init {
    if (self = [super init]) { // 1. 父類初始化
        // 2. 子類自身初始化
        _name = @"Default";
    }
    return self; // 必須返回初始化後的 self
}

若 [super init] 返回 nil,必須直接返回 nil,不執行後續代碼。

2. 重寫方法中調用父類實現


- (void)setName:(NSString *)name {
    [super setName:name]; // 先執行父類邏輯(如驗證、日誌)
    _name = name;         // 再執行子類邏輯
}

3. self 的動態綁定特性


// 父類
- (void)foo { NSLog(@"Parent foo"); }
- (void)bar { [self foo]; } // 調用 self 的 foo

// 子類重寫 foo
- (void)foo { NSLog(@"Child foo"); }

// 調用
Child *c = [[Child alloc] init];
[c bar]; // 輸出 "Child foo"!因為 self 是 Child 實例

4. super 的靜態綁定特性


// 子類
- (void)bar {
    [super foo]; // 總是調用 Parent 的 foo,無論 self 實際類型
}

編譯器視角

  • [self method] → objc_msgSend(self, @selector(method))
  • [super method] → objc_msgSendSuper(&super_struct, @selector(method))
  • super_struct 包含 receiver (self) 和 super_class (父類類對象)

常見錯誤

  1. 初始化不調用 [super init] → 父類成員未初始化
  2. if (self = [super init]) 寫成 if (self == [super init]) → 邏輯錯誤
  3. 在類方法中使用 self 指向類對象,super 指向元類父類
  4. 誤以為 super 是指針可賦值傳遞 → 編譯錯誤

總結

self 是動態的、多態的、面向對象的核心;super 是靜態的、顯式的、用於協作繼承的工具。理解二者查找差異,是掌握 Objective-C 運行時機制的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved