其中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中表示呼叫方法,包括兩種 類名 方法名 和 物件...