Clang
macOSプロジェクトを作成し、中のmain.mファイルをコンパイルします。clang -rewrite-objc main.m -o main.cppCompileコマンド: このコマンドでmain.mをcppファイルにコンパイルできます。
// macosコマンドライン項目
clang -rewrite-objc main.m -o main.cpp
clang -rewrite-objc
// UIKitライブラリへの参照
clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios- -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.5.sdk main.m
// xcrun xcode
xcrun -sdk iphonesimulator clang -arch -arm64 -rewrite-objc main.m -o main.m-arm64.cpp //
xcrun -sdk iphoneos clang -arch -arm64 -rewrite-objc main.m -o main.m-arm64.cpp //
コンパイル結果
main.mの内容は以下の通り:
#import <Foundation/Foundation.h>
@interface Person : NSObject {
NSString *nickname;
}
@property (weak, nonatomic) NSString * name;
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
}
return 0;
}
検索結果:124件
これらの結果を比較すると、LGPersonは次のようなcppファイルをコンパイルすることがわかります。
- Person クラスは objc_object 構造体にコンパイルされます:
- メンバー変数 nickname または nickname
- 属性名は_name
- name属性のゲッター・メソッドとセッター・メソッドの両方が生成されます。
#ifndef _REWRITER_typedef_Person
#define _REWRITER_typedef_Person
typedef struct objc_object Person;
typedef struct {} _objc_exc_Person;
#endif
extern "C" unsigned long OBJC_IVAR_$_Person$_name;
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *nickname;
NSString *_name;
};
// @property (copy, nonatomic) NSString * name;
/* @end */
// @implementation Person
static NSString * _I_Person_name(Person * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_Person$_name)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);
static void _I_Person_setName_(Person * self, SEL _cmd, NSString *name) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct Person, _name), (id)name, 0, 1); }
// @end
typedef struct objc_objectもう一度グローバル検索をかけると、843件の検索結果が得られますので、この構造が多くのものを定義していることがわかります。
では、一番下のobjc_objectとは一体何なのかというと、objc_object {で検索すればその定義を見つけることができます。objc_objectの定義は、objc_objectで検索すれば見つかります。クラスとidとSELもその上下に見つかりました。
typedef struct objc_class *Class;
struct objc_object {
Class _Nonnull isa __attribute__((deprecated));
};
typedef struct objc_object *id;
typedef struct objc_selector *SEL;
上記のコードから以下の結論が得られます:
- objc_objectは一番下の構造体です。
- idはobjc_object型の構造体へのポインタです。
- SELはobjc_selector型構造体へのポインタです。
- Classはobjc_class型の構造体へのポインタです。
メソッドとシグネチャの一覧
注:Xcode 11.5
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[4];
} _OBJC_$_INSTANCE_METHODS_Person __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
4,
{{(struct objc_selector *)"name", "@", (void *)_I_Person_name},
{(struct objc_selector *)"setName:", "v@16", (void *)_I_Person_setName_},
{(struct objc_selector *)"name", "@", (void *)_I_Person_name},
{(struct objc_selector *)"setName:", "v@16", (void *)_I_Person_setName_}}
};
"@16@0:8 "はメソッドのシグネチャです。
- @ は戻り値の型です。
- 16は全パラメータが占めるメモリの長さ
- は最初のパラメータタイプ
- 0は最初のパラメータの開始位置
- は2番目のパラメータの型です。
- 8は第2パラメータの開始位置
対応する記号の種類
- 印刷する
void types(){
NSLog(@"char --> %s",@encode(char));
NSLog(@"int --> %s",@encode(int));
NSLog(@"short --> %s",@encode(short));
NSLog(@"long --> %s",@encode(long));
NSLog(@"long long --> %s",@encode(long long));
NSLog(@"unsigned char --> %s",@encode(unsigned char));
NSLog(@"unsigned int --> %s",@encode(unsigned int));
NSLog(@"unsigned short --> %s",@encode(unsigned short));
NSLog(@"unsigned long --> %s",@encode(unsigned long long));
NSLog(@"float --> %s",@encode(float));
NSLog(@"bool --> %s",@encode(bool));
NSLog(@"void --> %s",@encode(void));
NSLog(@"char * --> %s",@encode(char *));
NSLog(@"id --> %s",@encode(id));
NSLog(@"Class --> %s",@encode(Class));
NSLog(@"SEL --> %s",@encode(SEL));
int array[] = {1,2,3};
NSLog(@"int[] --> %s",@encode(typeof(array)));
typedef struct person{
char *name;
int age;
}Person;
NSLog(@"struct --> %s",@encode(Person));
typedef union union_type{
char *name;
int a;
}Union;
NSLog(@"union --> %s",@encode(Union));
int a = 2;
int *b = {&a};
NSLog(@"int[] --> %s",@encode(typeof(b)));
}
- :





