1 void、void * 、id
1.1 void 和 void *
1.1.1 void
- 關鍵字表示“空類型”的抽象概念
- 但這里的“空類型”不表示“任意類型”,實際上它也不是一種類型,而是表示不存在的意思,也就是說C/C++不允許你寫語句void a,不存在類型為void的東西
- 作用:
1、對函數返回值進行限定
2、對函數傳入參數進行限定- (void)viewDidLoad { }
// 沒有參數的 block 屬性 @property (nonatomic, copy) void(^clickBlock)(void);
1.1.2 void *
- void *表示“任意類型的指針” 或 表示“該指針與一地址值相關,但是不清楚在此地址上的對象的類型”。
為什么不用void表示任意類型的數據呢?
大家都知道,C/C++是靜態類型的語言,定義變量就會分配內存,然而,不同類型的變量所占內存不同,如果定義一個任意類型的變量,如何為其分配內存呢?所以,C、C++中沒有任意類型的變量。
但是,所有指針類型的變量,無論是int、char、string、Student等等,他們的內存空間都是相同的,所以可以定義“任意類型的指針”。
- void * 指針只支持幾種有限的操作:
1 與另一個指針進行比較
2 向函數傳遞void * 指針或從函數返回void * 指針
3 給另一個void *指針賦值
不允許使用void * 指針操作它所指向的對象,例如,不允許對void * 指針進行解引用
不允許對void * 指針進行算術操作
1.1.2 REF
C語言void關鍵字_C語言中文網
C/C++中的函數中的void和void* 理解 - 程序園
1.2 id、NSObject
1.2.1 id 定義 和 官方解析-id
id define
- id是一個指針,用于表示OC 任意類型實例對象的指針,默認告訴編譯器該指針指向的對象可以調用任何方法,下面情況編譯通過
id aObject = nil;
[aObject appendString:@"xx"];
1.2.2 NSObject
- NSObject是 OC 類的基類對象(官方解析NSObject)
- NSObject 本質是C++的結構體,其表現形式(OC 轉 C++代碼方法參考NSObject 對象占用內存、isa/superclass指向、類信息存放 - 簡書)
在 C++文件中,NSObject表現形式如下
NSObject define
1.2.3 id 和 NSObject 定義對比
NSObject定義:typedef struct objc_object NSObject;
id 定義typedef struct objc_object *id;
其中 objc_object 定義:
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
- 所以,NSObject 是 objc_object類型結構體的別名,而 id 則是 objc_object類型結構體的的指針
- 即
id obj = [[NSObject alloc] init];
等同于NSObject *obj = [[NSObject alloc] init];
1.2.4 id 等同于 NSObject *嗎
- 不等同,id 沒有指定類型,而NSObject *則指定了類型即NSObject
id 編譯通過
NSObject *編譯不通過id aObject = nil; [aObject appendString:@"xx"];
NSObject *aObject = nil; [aObject appendString:@"xx"]; // error: No visible @interface for 'NSObject' declares the selector 'appendString:'
- 還需要理解一點就是,NSObject 是 OC 的基類,但是 OC 并非所有類都繼承自 NSObject,例如 NSProxy 類。或自定義的其他 OC 類,那么此時就需要引入 id來表示。
-
同上道理,id 一般用于 delegate 的聲明,因為一般情況下是不知道 delegate 的實際類型是什么
REF
- https://stackoverflow.com/a/7904028
- id vs NSObject vs id<NSObject> 原文版 翻譯版
1.3 id 和 void *
- id is a pointer to any type, but unlike void * it always points to an Objective-C object
- id 的定義
typedef struct objc_object *id;
,也就表明,它是表示一個結構體類型,而不是空 void 類型。在內存分布上即存放該指針的內存
2 nil、Nil、NSNull、NULL
- nil:指向一個對象的空指針(用于表示OC中的
空
實例對象)
NSString *str = nil;
- Nil:指向一個類的空指針(用于表示OC中的
空
類對象)
Class someClass = Nil;
- NSNull:用于表示集合對象(NSArray,NSDictionary,NSSet)中的空值
在集合對象中nil代表結束,故不能用nil代表空值存放于集合中
NSArray *arr = @[@"1", @"2", @"3", [NSNull null]];
- NULL:指向其他類型(基本數據類型,C語言類型)的空指針
// void * 類型的 context 參數,一般使用調用時,如果想不傳參給 context,此時正確做法是傳入 NULL
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
[self.person1 addObserver:self forKeyPath:@"age" options: NSKeyValueObservingOptionNew context:NULL]