OC代码的底层实现实质是 C/C++代码 ,继而编译成汇编代码,最终变成机器语言。
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
#import
#import
@interface YDWHandsomeBoy : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation YDWHandsomeBoy
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
}
return 0;
}
#ifndef _REWRITER_typedef_YDWHandsomeBoy
#define _REWRITER_typedef_YDWHandsomeBoy
typedef struct objc_object YDWHandsomeBoy;
typedef struct {
} _objc_exc_YDWHandsomeBoy;
#endif
extern "C" unsigned long OBJC_IVAR_$_YDWHandsomeBoy$_name;
struct YDWHandsomeBoy_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *_name;
};
// @property (nonatomic, copy) NSString *name;
/* @end */
// @implementation YDWHandsomeBoy
struct NSObject_IMPL {
Class isa;
};
NSObject *obj = [[NSObject alloc] init];
NSLog(@"%zd",malloc_size((__bridge const void *)obj));
NSLog(@"%zd",class_getInstanceSize([NSObject class]))
#import
#import
#import
@interface YDWHandsomeBoy : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) int address;
@property (nonatomic, assign) int number;
@end
@implementation YDWHandsomeBoy
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
YDWHandsomeBoy *boy = [[YDWHandsomeBoy alloc] init];
boy.name = @"Y";
boy.nickName = @"D";
boy.age = 18;
boy.address = 10;
boy.number = 11;
NSLog(@"%zd",malloc_size((__bridge const void *)boy));
}
return 0;
}
打印结果如下:
2020-09-02 15:44:27.345192+0800 iOS之对象isa[53982:3621024] 48
union isa_t {
isa_t() {
}
isa_t(uintptr_t value) : bits(value) {
}
Class cls;
uintptr_t bits;
#if defined(ISA_BITFIELD)
struct {
ISA_BITFIELD; // defined in isa.h
};
#endif
};
union isa_t {
isa_t() {
}
isa_t(uintptr_t value) : bits(value) {
}
Class cls;
uintptr_t bits;
#if defined(ISA_BITFIELD)
struct {
ISA_BITFIELD; // defined in isa.h
};
#endif
};
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 8
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
struct {
uintptr_t indexed : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 44;
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8;
};
isa 作为一个联合体,有一个结构体属性为 ISA_BITFIELD ,其大小为 8 个字节,也就是 64 位。基于__arm64__ 和 x86 64 架构如下:
# if __arm64__
# define ISA_MASK 0x0000000ffffffff8ULL
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 19
# define RC_ONE (1ULL<<45)
# define RC_HALF (1ULL<<18)
# elif __x86_64__
# define ISA_MASK 0x00007ffffffffff8ULL
# define ISA_MAGIC_MASK 0x001f800000000001ULL
# define ISA_MAGIC_VALUE 0x001d800000000001ULL
# define ISA_BITFIELD \
uintptr_t nonpointer : 1; \
uintptr_t has_assoc : 1; \
uintptr_t has_cxx_dtor : 1; \
uintptr_t shiftcls : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
uintptr_t magic : 6; \
uintptr_t weakly_referenced : 1; \
uintptr_t deallocating : 1; \
uintptr_t has_sidetable_rc : 1; \
uintptr_t extra_rc : 8
# define RC_ONE (1ULL<<56)
# define RC_HALF (1ULL<<7)
# else
# error unknown architecture for packed isa
# endif
inline void
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor) {
assert(!cls->instancesRequireRawIsa());
assert(hasCxxDtor == cls->hasCxxDtor());
initIsa(cls, true, hasCxxDtor);
}
inline void
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) {
assert(!isTaggedPointer());
if (!nonpointer) {
isa.cls = cls;
} else {
assert(!DisableNonpointerIsa);
assert(!cls->instancesRequireRawIsa());
isa_t newisa(0);
#if SUPPORT_INDEXED_ISA
assert(cls->classArrayIndex() > 0);
newisa.bits = ISA_INDEX_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
newisa.bits = ISA_MAGIC_VALUE;
// isa.magic is part of ISA_MAGIC_VALUE
// isa.nonpointer is part of ISA_MAGIC_VALUE
newisa.has_cxx_dtor = hasCxxDtor;
newisa.shiftcls = (uintptr_t)cls >> 3;
#endif
// This write must be performed in a single store in some cases
// (for example when realizing a class because other threads
// may simultaneously try to use the class).
// fixme use atomics here to guarantee single-store and to
// guarantee memory order w.r.t. the class index table
// ...but not too atomic because we don't want to hurt instantiation
isa = newisa;
}
}
inline void
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) {
isa_t newisa(0);
newisa.bits = ISA_MAGIC_VALUE;
newisa.has_cxx_dtor = hasCxxDtor;
newisa.shiftcls = (uintptr_t)cls >> 3;
isa = newisa;
}
newisa.has_cxx_dtor = hasCxxDtor;
newisa.shiftcls = (uintptr_t)cls >> 3;
isa 是对象中的第一个属性,这是在继承的时候发生的,要早于对象的成员变量,属性列表,方法列表以及所遵循的协议列表。在 alloc 底层,有一个方法叫做 initIsa ,这个方法的作用就是 初始化 isa 联合体位域 。上文中我们已经看到了这个方法:
newisa.shiftcls = (uintptr_t)cls >> 3;
(lldb) p/t 8303511812964353
(long) $3 = 0b0000000000011101100000000000000000000000000000000000000000000001
(lldb) p/t (uintptr_t)cls
(uintptr_t) $4 = 0b0000000000000000000000000000000100000000010001110100000000111000
(lldb) p/t (uintptr_t)cls >> 3
(uintptr_t) $5 = 0b0000000000000000000000000000000000100000000010001110100000000111
(lldb)
struct objc_object {
private:
isa_t isa;
...
};
struct objc_class : objc_object {
// Class ISA;
Class superclass;
// 方法缓存
cache_t cache; // formerly cache pointer and vtable
// 用于获取具体的类信息
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
...
};
struct objc_class : objc_object {
isa_t isa;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
...
};
OBJC_EXPORT BOOL class_isMetaClass(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
OBJC_EXPORT Class object_getClass(id obj)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
Class class1 = [Boy class];
Class class2 = [Boy alloc].class;
Class class3 = object_getClass([Boy alloc]);
Class class4 = [Boy alloc].class;
NSLog(@"\n%p-\n%p-\n%p-\n%p",class1, class2, class3, class4);
// 打印如下:
0x10edbedc8
0x10edbedc8
0x10edbedc8
0x10edbedc8
struct objc_object {
private:
isa_t isa;
public:
// ISA() assumes this is NOT a tagged pointer object
Class ISA();
// getIsa() allows this to be a tagged pointer object
Class getIsa();
......
}
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
......
}