一、類的結構
OC 中的代碼在底層實現,使用的是 C、C++,所以要研究 OC 中的類結構,可以將 OC 的代碼轉成 C++的代碼即可。首先看一下 NSObject 的結構是什么樣子的,創建一個文件并簡單的編寫如下代碼:
// CustomFile.m#import <Foundation/Foundation.h>void test() { [NSObject alloc];}
進入終端,輸入指令:
clang -rewrite-objc CustomFile.m
默認生成一個 CustomFile.cpp 文件。這個指令生成的代碼會很多,也可以使用 xcrun 指令來指定一個特定的架構,這樣的:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc CustomFile.m -o CustomFile_arm64.cpp
這樣在 CustomFile_arm64.cpp 文件中會生成一個 真機下的運行代碼。相比之下 CustomFile_arm64.cpp 文件會比 CustomFile.cpp 小了很多,但是對于查看 NSObject 的實際結構都是可以的。
打開任意一個 .cpp 文件,都可以找到這樣的定義:
struct NSObject_IMPL { Class isa;};
其中 Class 的定義如下:
typedef struct objc_class *Class;
再來看一下在實際中的 NSObject 類的聲明是什么樣的:
@interface NSObject <NSObject> {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wobjc-interface-ivars" Class isa OBJC_ISA_AVAILABILITY;#pragma clang diagnostic pop}
簡化后是這樣的:
@interface NSObject { Class isa;}
總之Class 是一個指針,NSObject_IMPL是一個結構體,與 NSObject 在結構上極為相似。
二、類繼承后的結構
創建一個 Person.m 文件,弄一個繼承于 NSObject 的 Person 類。代碼編寫如下:
// Person.m#import <Foundation/Foundation.h>// 類的申明@interface Person : NSObject@end// 類的實現@implementation Person@end// 類的申明@interface Student : Person@end// 類的實現@implementation Student@end
其中 Person 繼承于 NSObject,Student 繼承于 Person 于是在 .cpp 文件中找到這樣的定義:
struct Person_IMPL { struct NSObject_IMPL NSObject_IVARS;};struct Student_IMPL { struct Person_IMPL Person_IVARS;};
NSObject_IVARS 看著這個命名就可以猜到是將父類的所有 ivar 都繼承過來了。
似乎明白了一個套路
在 NSObject 中只有一個 Class 類型的成員變量 isa,在沒有自定義任何的成員屬性的情況下,繼承的子類中的 ivar 都來自于父類。
如果說給 Person 與 Student 都定義一個成員變量,是這樣的:
struct Person_IMPL { struct NSObject_IMPL NSObject_IVARS; int _no;};struct Student_IMPL { struct Person_IMPL Person_IVARS; int _age;};
終于對 Class 的一些套路有進一步的理解了。
三、添加方法后的結構
創建一個 FunClass.m 文件,編寫代碼如下:
// FunClass.m#import <Foundation/Foundation.h>// 類的申明@interface FunClass : NSObject- (void)testInstance;+ (void)testClass;@end// 類的實現@implementation FunClass- (void)testInstance { }+ (void)testClass { }@end
最后發現在 .cpp 中類的結構沒有任何的改變,是這樣的:
struct FunClass_IMPL { struct NSObject_IMPL NSObject_IVARS;};
但是我們會發現另外一個問題,在 OC 中的方法變成這樣的了:
// 實例方法_OBJC_$_INSTANCE_METHODS_FunClass __attribute__ ((used, section ("__DATA,__objc_const"))) = { sizeof(_objc_method), 1, {{(struct objc_selector *)"testInstance", "v16@0:8", (void *)_I_FunClass_testInstance}}static void _I_FunClass_testInstance(FunClass * self, SEL _cmd) {}// 類方法_OBJC_$_CLASS_METHODS_FunClass __attribute__ ((used, section ("__DATA,__objc_const"))) = { sizeof(_objc_method), 1, {{(struct objc_selector *)"testClass", "v16@0:8", (void *)_C_FunClass_testClass}}static void _C_FunClass_testClass(Class self, SEL _cmd) {}
發現這幾個特點:
1、實例方法有這個:_INSTANCE_METHODS_FunClass,類方法的是這個:_CLASS_METHODS_FunClass
2、兩個方法都是 static 方法
3、方法都多了兩個參數:self 與_cmd,這也回答了為什么 self 與 _cmd 只能在方法中有的根本原因。
關于 方法 的這部分先介紹到這里,后期會有專門的專題。
四、自定義一個 Class 與對應的結構體
在线电影欧美日韩一区二区私密| 国外成人在线播放| 国产精品三级美女白浆呻吟| 欧美成人免费va影院高清| 国产精品久久久久久久一区探花| 国产精品久久久久aaaa九色| 国产精品久久久久久久久久新婚| 精品国产一区二区三区久久久| 亚洲美女性视频| 色综合久久中文字幕综合网小说| 亚洲精品久久久久久久久久久| 黑人巨大精品欧美一区免费视频| 91国产视频在线播放| 亚洲综合自拍一区| 亚洲最大福利视频网| 97激碰免费视频| 久99九色视频在线观看| 欧美一区二区三区四区在线| 亚洲精品电影久久久| 久久中文字幕在线| 亚洲日韩欧美视频一区| 亚洲已满18点击进入在线看片| 亚洲第一网中文字幕| 亚洲精品视频网上网址在线观看| 亚洲成年网站在线观看| 欧美成人剧情片在线观看| 久久6精品影院| 欧美日韩加勒比精品一区| 久久久av网站| 日韩在线视频网| 成人午夜在线视频一区| 国产精品高清免费在线观看| 狠狠久久五月精品中文字幕| 欧美在线观看视频| 一区二区三区 在线观看视| 久久精品国产2020观看福利| 国内精品视频一区| 亚洲国产欧美一区| 国产成人拍精品视频午夜网站| 亚洲男人天堂九九视频| 欧美怡红院视频一区二区三区| 欧美国产在线电影| 性欧美视频videos6一9| 色综合导航网站| 日韩电影中文字幕在线| 乱亲女秽乱长久久久| 伊人久久五月天| 91久久国产精品91久久性色| 国产午夜精品视频免费不卡69堂| 2019精品视频| 亚洲人成网站777色婷婷| 日韩精品999| 在线成人激情视频| 亚洲va国产va天堂va久久| 欧美日本高清视频| 国产噜噜噜噜噜久久久久久久久| 国产日韩换脸av一区在线观看| 日本高清不卡在线| 国产午夜精品美女视频明星a级| 久热精品视频在线观看一区| 亚洲精品电影在线| 97免费中文视频在线观看| 日韩成人av网址| 欧美成人黄色小视频| 亚洲国产精品久久久久秋霞蜜臀| 国产一区二区三区毛片| 国产自产女人91一区在线观看| 51色欧美片视频在线观看| 日韩中文在线中文网三级| 美日韩在线视频| 亚洲欧洲一区二区三区在线观看| 精品久久久久久久久久ntr影视| 欧美电影免费播放| 狠狠色狠色综合曰曰| 亚洲一区二区日本| 精品偷拍各种wc美女嘘嘘| 91超碰中文字幕久久精品| 色狠狠久久aa北条麻妃| 亚洲国产精品va在线| 伊人伊人伊人久久| 91欧美日韩一区| 国产精品吹潮在线观看| 亚洲精品一区二区三区不| 91av在线播放| 日韩在线观看你懂的| 8050国产精品久久久久久| 久久精品久久久久| 激情久久av一区av二区av三区| 亚洲国内精品在线| 亚洲色图国产精品| 国产午夜精品全部视频在线播放| 日韩欧美中文在线| 国产成人综合久久| 欧美激情乱人伦一区| 欧美一区二区影院| 欧美日韩在线观看视频| 亚洲新中文字幕| 国产精品久久久久久超碰| 91精品视频观看| 亚洲欧美制服丝袜| 91国产视频在线播放| 欧美午夜精品久久久久久久| 69视频在线免费观看| 国产精品免费一区豆花| 国产精品久久久久91| 欧美俄罗斯乱妇| 日韩精品中文字幕视频在线| 亚洲石原莉奈一区二区在线观看| 日韩av网址在线观看| 亚洲精品一区二区在线| 欧美激情视频播放| 欧美日韩精品二区| 亚洲天堂成人在线视频| 91久久久国产精品| 欧美精品videossex88| 国产精品精品国产| 日韩精品在线观| 欧美激情亚洲另类| 日韩av大片免费看| 91在线观看免费观看| 国产精品自产拍高潮在线观看| 国产精品一区二区三区在线播放| 亚洲精品福利在线观看| 国产精品久久久久影院日本| 日韩美女视频中文字幕| 亚洲va欧美va在线观看| 搡老女人一区二区三区视频tv| 韩剧1988在线观看免费完整版| 欧美野外wwwxxx| 日韩av电影院| 久久国产精品偷| 欧美电影在线播放| 一区二区在线视频播放| 国产精品亚洲自拍| 欧美野外猛男的大粗鳮| 亚洲免费福利视频| 日韩欧美精品在线观看| 亚洲一区二区国产| 亚洲丁香久久久| 日本不卡免费高清视频| 日韩电影中文字幕一区| 色777狠狠综合秋免鲁丝| 欧美专区第一页| 亚洲国产欧美在线成人app| 国产精品久久久久久av福利软件| 美女av一区二区| 欧美激情国产日韩精品一区18| 久久久久久久国产| 亚洲已满18点击进入在线看片| 日本精品久久久| 91高清视频在线免费观看| 一区二区欧美亚洲| 欧美xxxx18性欧美| 国产精品国产福利国产秒拍| 国产精品久久色| 国产精品久久久久久久久影视| 亚洲人成电影在线观看天堂色| 国产精品久久久av久久久| 国产z一区二区三区| 久久天天躁狠狠躁夜夜躁| 欧美午夜xxx| 久久精品视频99| 91在线国产电影| 中文字幕日韩有码|