OC中物件和類的本質手寫結構體筆記

2021-09-12 01:48:41 字數 3972 閱讀 1961

其中myclassinfo.h

#ifndef myclassinfo_h

#define myclassinfo_h

# if __arm64__

# define isa_mask 0x0000000ffffffff8ull

# elif __x86_64__

# define isa_mask 0x00007ffffffffff8ull

#endif

#if __lp64__

typedef uint32_t mask_t;

#else

typedef uint16_t mask_t;

#endif

typedef uintptr_t cache_key_t;

struct bucket_t ;

struct cache_t ;

struct entsize_list_tt ;

struct method_t ;

struct method_list_t : entsize_list_tt ;

struct ivar_t ;

struct ivar_list_t : entsize_list_tt ;

struct property_t ;

struct property_list_t : entsize_list_tt ;

//struct chained_property_list ;

typedef uintptr_t protocol_ref_t;

struct protocol_list_t ;

struct class_ro_t ;

struct class_rw_t ;

#define fast_data_mask 0x00007ffffffffff8ul

struct class_data_bits_t

};/* oc物件 */

struct my_objc_object ;

/* 類物件 */

struct my_objc_class : my_objc_object

my_objc_class* metaclass()

};#endif /* myclassinfo_h */ /*

關於typedef的用法

用法一:

定義一種型別的別名,而不是簡單的巨集替換,用於宣告指標型的多個物件.

比如:char *pa,pb; // 只宣告了乙個指向字元變數的指標,和乙個字元變數

而:typedef char* pchar;

pchar pa,pb; //定義了兩個字元型指標

用法二:

用typedef來定義與平台無關的型別.

比如定義乙個叫real的浮點型別,

在平台一上,讓它表示最高精度的型別為:

typedef long double real;

在不支援long double的平台二上,改為:

typedef double real;

在連double都不支援的平台三上,改為:

typedef float real;

也就是說,當跨平台時,只要改下typedef本身就行,不用對其他原始碼做任何修改

標準庫就廣泛使用了這個技巧,比如size_t。另外,因為typedef是定義了一種型別的新別名,不是簡單的字串替換,所以它比巨集來得穩健。

用法三:

為複雜的宣告定義乙個新的簡單的別名.

舉例:原宣告:void (*b[10]) (void (*)());

變數名為b,先替換右邊部分括號裡的,pfunparam為別名一:

typedef void (*pfunparam)();

再替換左邊的變數b,pfunx為別名二:

typedef void (*pfunx)(pfunparam);

原宣告的最簡化版:

pfunx b[10];

原宣告:doube(*)() (*e)[9];

變數名為e,先替換左邊部分,pfuny為別名一:

typedef double(*pfuny)();

再替換右邊的變數e,pfunparamy為別名二

typedef pfuny (*pfunparamy)[9];

原宣告的最簡化版:

pfunparamy e;

理解複雜宣告可用的「右左法則」:從變數名看起,先往右,再往左,碰到乙個圓括號

就調轉閱讀的方向;括號內分析完就跳出括號,還是按先右後左的順序,如此迴圈,直

到整個宣告分析完。舉例:

int (*func)(int *p);

首先找到變數名func,外面有一對圓括號,而且左邊是乙個*號,這說明func是乙個指標

;然後跳出這個圓括號,先看右邊,又遇到圓括號,這說明(*func)是乙個函式,所以

func是乙個指向這類函式的指標,即函式指標,這類函式具有int*型別的形參,返回值

型別是int。

int (*func[5])(int *);

func右邊是乙個運算子,說明func是具有5個元素的陣列;func的左邊有乙個*,說明

func的元素是指標(注意這裡的*不是修飾func,而是修飾func[5]的,原因是運算子

優先順序比*高,func先跟結合)。跳出這個括號,看右邊,又遇到圓括號,說明func數

組的元素是函式型別的指標,它指向的函式具有int*型別的形參,返回值型別為int。

疑惑的地方

int *p[3]和int(*p)[3]的區別

int *p[3],其中p是乙個陣列,此陣列有3個元素,每個元素都是int*型別,也就是指向整型資料的指標型別

int a = 10, b = 20, c = 30;

int *p[3] = ;// 指標陣列,陣列中的每乙個元素儲存的是int型別的指標

而int(*p)[3]中的p是乙個指向陣列的指標,此陣列有3個int型別的元素,例如

int a[3] = ;

int (*p)[3] = &a;//取陣列a的位址值. 陣列指標,p儲存指向乙個陣列的指標

*/

main.mm中

#import #import "myclassinfo.h"

@inte***ce person : nsobject

@property (nonatomic, assign)int no;

- (void)personinstancemethod;

+ (void)personclassmethod;

@end

@implementation person

- (void)personinstancemethod

+ (void)personclassmethod

- (id)copywithzone:(nszone *)zone

@end

@inte***ce student : person

@property (nonatomic, assign) int height;

- (void)studentinstancemethod;

+ (void)studentclassmethod;

@end

@implementation student

- (void)studentinstancemethod

+ (void)studentclassmethod

- (instancetype)initwithcoder:(nscoder *)adecoder

- (void)encodewithcoder:(nscoder *)acoder

@end

void mhftest()

int main(int argc, char * ar**) }

檢視物件內部結構體的分布情況

oc中類和物件

類與物件的概念 類是對同一類事物高度的抽象,類中定義了這一類物件所應具有的靜態屬性 屬性 和動態屬性 方法 物件是類的乙個例項,是乙個具體的事物。類與物件是抽象與具體的關係。類其實就是一種資料型別,它的變數就是物件。類與類之間的關係 繼承關係 a是b如果這句話說的通,在設計程式的時候就可以看成是繼承...

OC語言類的本質和分類

oc語言類的深入和分類 一 分類 一 分類的基本知識 概念 category 分類是oc特有的語言,依賴於類。分類的作用 在不改變原來的類內容的基礎上,為類增加一些方法。新增乙個分類 二 分類的使用注意 1 分類只能增加方法 包括類方法和物件方法 不能增加成員變數 2 在分類方法的實現中可以訪問原來...

oc中建立類和物件

一 建立類,得到物件 例1 1.新建乙個people類 繼承nsobject,得到 people.h和people.m以及main.m三個檔案 2.在main.m中,進行 物件化 專業來講也就是 例項化 如下 1 在這裡 號代表指標的意思。2 號在oc中表示呼叫方法,包括兩種 類名 方法名 和 物件...