car*_*rem 5 typedef objective-c
在Objective-C中,id是一个typedef:
typedef struct objc_object {
Class isa;
} *id;
Run Code Online (Sandbox Code Playgroud)
所以我可以声明(并初始化)一个变量,例如:
// using id
id po_one = @"one";
Run Code Online (Sandbox Code Playgroud)
编译好.
因为我在自己的方案中命名我的类型,因为我不喜欢id typedef中的隐含指针,我想添加一个自己的typedef(对象为O),如下所示:
typedef struct objc_object O;
Run Code Online (Sandbox Code Playgroud)
所以变量声明(带初始化)可能如下所示:
// using O
O * po_two = @"two";
Run Code Online (Sandbox Code Playgroud)
这会编译一个警告:
从不兼容的指针类型初始化
据我所知,typedef我认为后者应该相当于:
// using struct objc_object
struct objc_object * po_three = @"three";
Run Code Online (Sandbox Code Playgroud)
这再次编译好.
令人惊讶的是:
po_two = po_one;
po_two = po_three;
Run Code Online (Sandbox Code Playgroud)
两者都编译没有警告.
所以我尝试过:
typedef struct objc_object * PO;
Run Code Online (Sandbox Code Playgroud)
如果我包含指针(完全是我想要避免的东西 - 因此只是出于测试原因),看看它是否在没有警告的情况下工作,以查看结构定义之外的typedef是否与结构定义中的typedef不同(这是在这种情况下id的定义).
// using PO
PO po_four = @"four";
Run Code Online (Sandbox Code Playgroud)
这也很好.
如果我使用:
#define O struct objc_object
Run Code Online (Sandbox Code Playgroud)
使用O的构造在没有警告的情况下再次编译.
但我更喜欢尽可能使用typedef而不是定义.
我很困惑.我对typedef的误解是什么?
我不是编译器专家,所以真正的专家可能会给你更好的答案。无论如何,根据我的知识,当编译器进行类型检查时,它会基于“解析树”进行检查,该树为所有可能的数据类型结构生成一种表,并检查两个定义是否指向同一行在表中。因此它的工作原理是从该表中获取符号和类型定义并进行比较。现在“struct objc_object”就是这些数据结构之一。然后,当定义 id 时,它会生成另一个条目:“id --> struct objc_object *”。po_two 定义导致相同的引用:“struct objc_object *”(事实上“=”具有最低优先级)。po_four 也会发生同样的情况,因为根据定义,PO 再次指向相同的引用(PO --> struct objc_object *)。当您使用 #define 定义时,由于预处理,您仍然引用“struct objc_object *”。但是当你使用
O * po_two = @"two"Run Code Online (Sandbox Code Playgroud)实际上,您正在尝试匹配一种类型“id”(@“two”),即“struct objc_object *”,另一种类型是指向“struct objc_object”的指针,但即使逻辑上它们是相同的不要导致表中相同的引用。原因是因为“O”类型尚未定义,所以 po_two 只是作为指向“O”和“O --> struct objc_object”的指针存储在符号表中。这就是警告的原因:po_two 是一个指向与 @"two" 不同的东西的指针。
我很好奇:您是否尝试过使用“nm”绘制符号表?
| 归档时间: |
|
| 查看次数: |
1984 次 |
| 最近记录: |