什么是对象
Clang
Clang是C语言、C++、Objective-c语言的轻量编译器。源代码发布于BSD协议下。
Clang将支持lambad表达式,返回类型的简单处理以及更好的处理constexpr关键字。
Clang有Apple主导编写,基于LLVM的C/C++/Objective-c编译器
准备阶段
将 main.m 编译成 main.cpp 文件
clang -rewrite-objc main.m -o main.cpp
复制代码
如果出现
In file included from ViewController.m:9:
./ViewController.h:9:9: fatal error: 'UIKit/UIKit.h' file not found
#import <UIKit/UIKit.h>
^~~~~~~~~~~~~~~
1 error generated.
复制代码
解决办法
clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-13.0.0 -isysroot /
Applications/Xcode.app/Contents/Developer/Platforms/
iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.0.sdk main.m
复制代码
xcrun编译
//模拟器
xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o
main-arm64.cpp
//真机
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o
main-arm64.cpp
复制代码
分析阶段
main.m 声明一个 LGPerson
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface LGPerson : NSObject
@property (nonatomic, strong) NSString *Name;
@end
@implementation LGPerson
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
复制代码
在生成的main.cpp文件中找到LGPerson对应的地方
struct LGPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *_Name;
};
复制代码
- 对比 .m 文件可以得出结论对象在底层的本质是结构体,
然后在文件中查找 struct NSObject_IMPL 结构体发现
struct NSObject_IMPL {
Class isa;
};
复制代码
-
得出结论 NSObject_IVARS是成员变量isa
-
LGPerson是继承 NSObject,在cpp文件中是 objc_object 类型,所以 NSObject 对象在底层的类型是 objc_object
typedef struct objc_object NSObject;
复制代码
- 查找浏览cpp文件还发现,我们通常声明一个类时使用的 Class 的类型是
objc_class *,是一个结构体指针
typedef struct objc_class *Class;
复制代码
- id 的类型是
objc_object *,所以可以定义任何类型的变量
typedef struct objc_object *id;
复制代码
- getter/setter 隐藏参数:在.cpp文件中查找 LGPerson 的get/set方法
//getter
static NSString * _I_LGPerson_Name(LGPerson * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_LGPerson$_Name)); }
//setter
static void _I_LGPerson_setName_(LGPerson * self, SEL _cmd, NSString *Name) { (*(NSString **)((char *)self + OBJC_IVAR_$_LGPerson$_Name)) = Name; }
复制代码
结构体 联合体 位域
案例一
#import <Foundation/Foundation.h>
struct LGPerson {
bool left;
bool right;
bool front;
bool back;
};
struct LGPersonEx {
bool left: 1;
bool right: 1;
bool front: 1;
bool back: 1;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
struct LGPerson p1;
NSLog(@"-%lu-",sizeof(p1));
struct LGPersonEx p2;
NSLog(@"-%lu-",sizeof(p2));
}
return 0;
}
复制代码
打印sizeof结果为:p1占用4字节空间, p2占用1字节空间
案例二
struct LGPerson {
NSString *name;
int age;
};
union LGPersonEx {
NSString *name;
int age;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
struct LGPerson p1;
p1.name = @"swagger";
p1.age = 18;
NSLog(@"-%lu-",sizeof(p1));
union LGPersonEx p2;
p2.name = @"swagger";
p2.age = 18;
NSLog(@"-%lu-",sizeof(p2));
}
return 0;
}
复制代码
在p1和p2赋值的过程中分别打断点,.name = @"swagger"; .age = 18;
(lldb) p p1
(LGPerson) $0 = (name = 0x0000000000000000, age = 0)
(lldb) p p1
(LGPerson) $1 = (name = @"swagger", age = 0)
(lldb) p p1
(LGPerson) $2 = (name = @"swagger", age = 18)
(lldb) p p2
(LGPersonEx) $0 = (name = 0x0000000000000000, age = 0)
(lldb) p p2
(LGPersonEx) $1 = (name = "swagger", age = 16284)
(lldb) p p2
(LGPersonEx) $2 = (name = "", age = 18)
(lldb)
复制代码
结论:
通过案例一,结构体内声明了4个bool类型,占用4字节内存,对结构体内声明的4个bool类型进行指定位域,指定每一个bool类型的成员变量使用1bit的内存空间,那么4个bool类型最终占用4bit空间,即0.5字节的空间,最终占用了1字节内存,为对象指定位域是内存优化的方式
通过案例二,也就是struct与union的区别,struct内成员变量的存储互不影响,union内的对象存储是互斥的
结构体(struct)中所有的变量是共存的,优点是可以存储所有的对象的值,比较全面。缺点是struct内存空间分配是粗放的,不管是否被使用,全部分配
联合体(union)中所有的变量是互斥的,优点是内存使用更加精细灵活,也节省了内存空间,缺点就是不够包容
nonpointerIsa初探
isa指针存了什么
通过宏定义ISA_BITFIELD找到了isa指针内都存放了什么, 分为两种模式
- arm64
define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
# define ISA_HAS_CXX_DTOR_BIT 1
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; //是否为纯指针 \
uintptr_t has_assoc : 1; //关联对象 \
uintptr_t has_cxx_dtor : 1; //C++的析构函数 \
uintptr_t shiftcls : 33; / *MACH_VM_MAX_ADDRESS 0x1000000000*/ \ //类的指针地址
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; //弱引用 \
uintptr_t unused : 1; \
uintptr_t has_sidetable_rc : 1; //散列表 \
uintptr_t extra_rc : 19 //引用计数
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
复制代码
- x86_64
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
# define ISA_HAS_CXX_DTOR_BIT 1
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; //是否为纯指针 \
uintptr_t has_assoc : 1; //关联对象 \
uintptr_t has_cxx_dtor : 1; //C++的析构函数 \
uintptr_t shiftcls : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \ //类的指着地址
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; //弱引用 \
uintptr_t unused : 1; \
uintptr_t has_sidetable_rc : 1; //散列表 \
uintptr_t extra_rc : 8 //引用计数
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
复制代码
图形分析




明月别枝惊鹊 清风半夜鸣蝉























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)