一、面向对象
苹果的开源网站:https://opensource.apple.com/tarballs/
![](https://img.haomeiwen.com/i6434429/df0ccef62a8e94e3.png)
![](https://img.haomeiwen.com/i6434429/a384736fd054813f.png)
![](https://img.haomeiwen.com/i6434429/19b5f86e94d7508e.png)
![](https://img.haomeiwen.com/i6434429/2dd1a09eae5c1a5c.png)
![](https://img.haomeiwen.com/i6434429/8436aab0d44992d1.png)
![](https://img.haomeiwen.com/i6434429/a09789dbf2e529c8.png)
![](https://img.haomeiwen.com/i6434429/5a2f7d1e8da5d4b1.png)
![](https://img.haomeiwen.com/i6434429/27ab3a23c440e8f2.png)
![](https://img.haomeiwen.com/i6434429/1ecc26f277b61848.png)
1.内存对齐:结构体的最终大小必须是最大成员大小的倍数
2.一个OC对象,系统至少分配16字节
3.系统为对象分配内存时是16倍数
![](https://img.haomeiwen.com/i6434429/e4171f6b54bd7960.png)
![](https://img.haomeiwen.com/i6434429/a4f06f18e83b369b.png)
sizeof()是运算符,不是函数,在编译时就确定占用多少内存空间,而class_getInstanceSize()和malloc_size()是在程序运行过程中根据参数确定内存空间
二、OC对象的分类
![](https://img.haomeiwen.com/i6434429/5e09304cf3403e69.png)
1、instance对象
![](https://img.haomeiwen.com/i6434429/df96d6d27964ba10.png)
2、Class对象
![](https://img.haomeiwen.com/i6434429/1e6b7dfd6d57e8eb.png)
3、meta-class对象
![](https://img.haomeiwen.com/i6434429/fd4735b62e5f9851.png)
总结:
- Class object_getClass(id obj): (runtime的api)
1、如果传入参数的是实例(instance)对象,那么返回的是类(Class)对象
2、如果传入的参数是类(Class)对象,那么返回的是元类(meta-class)对象
3、如果传入的参数是元类(meta-class)对象,那么返回的是基类(NSObject)的元类(meta-class)对象 - Class objc_getClass(const char *aClassName): (runtime的api)
传入的参数是字符串类名:如果找到给字符串对应的类就返回类对象,找不到的话就返回nil - -(Class)class 和 +(Class)class
1、返回类对象
三、isa指针
![](https://img.haomeiwen.com/i6434429/defb0e31b0554c60.png)
1、验证instance对象的isa指针指向的是Class对象
![](https://img.haomeiwen.com/i6434429/be61cd29999261d3.png)
2、验证Class对象的isa指向的是元类对象
![](https://img.haomeiwen.com/i6434429/cb979a79d8a7ce41.png)
四、superclass指针
1、类对象的superclass指针
![](https://img.haomeiwen.com/i6434429/4d35938f22bc1418.png)
![](https://img.haomeiwen.com/i6434429/6b1e4ace05fd9567.png)
2、元类对象的superclass指针
![](https://img.haomeiwen.com/i6434429/0a7bbafd6c6ea414.png)
总结:
![](https://img.haomeiwen.com/i6434429/dcd1a02986295b77.png)
![](https://img.haomeiwen.com/i6434429/b80b4cd5e33aed1c.png)
![](https://img.haomeiwen.com/i6434429/0412e97ac8050372.png)
![](https://img.haomeiwen.com/i6434429/29823bf581daa9ce.png)
总结:OC的方法调用时不知道调用的是类方法或者对象方法,只知道给某个对象发送消息
五、Class的结构
![](https://img.haomeiwen.com/i6434429/74f2702a2713198f.png)
![](https://img.haomeiwen.com/i6434429/c79e2650b6b663b9.png)
验证类对象和元类对象struct objc_class 结构,存储的bits信息(方法信息、属性信息、协议信息)
![](https://img.haomeiwen.com/i6434429/b5a8523ba7487911.png)
代码如下:
------------------------MJClassInfo.h-----------------------
#import <Foundation/Foundation.h>
#ifndef MJClassInfo_h
#define MJClassInfo_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 {
cache_key_t _key;
IMP _imp;
};
struct cache_t {
bucket_t *_buckets;
mask_t _mask;
mask_t _occupied;
};
struct entsize_list_tt {
uint32_t entsizeAndFlags;
uint32_t count;
};
struct method_t {
SEL name;
const char *types;
IMP imp;
};
struct method_list_t : entsize_list_tt {
method_t first;
};
struct ivar_t {
int32_t *offset;
const char *name;
const char *type;
uint32_t alignment_raw;
uint32_t size;
};
struct ivar_list_t : entsize_list_tt {
ivar_t first;
};
struct property_t {
const char *name;
const char *attributes;
};
struct property_list_t : entsize_list_tt {
property_t first;
};
struct chained_property_list {
chained_property_list *next;
uint32_t count;
property_t list[0];
};
typedef uintptr_t protocol_ref_t;
struct protocol_list_t {
uintptr_t count;
protocol_ref_t list[0];
};
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize; // instance对象占用的内存空间
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name; // 类名
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars; // 成员变量列表
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
};
struct class_rw_t {
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_list_t * methods; // 方法列表
property_list_t *properties; // 属性列表
const protocol_list_t * protocols; // 协议列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
};
#define FAST_DATA_MASK 0x00007ffffffffff8UL
struct class_data_bits_t {
uintptr_t bits;
public:
class_rw_t* data() {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
};
/* OC对象 */
struct mj_objc_object {
void *isa;
};
/* 类对象 */
struct mj_objc_class : mj_objc_object {
Class superclass;
cache_t cache;
class_data_bits_t bits;
public:
class_rw_t* data() {
return bits.data();
}
mj_objc_class* metaClass() {
return (mj_objc_class *)((long long)isa & ISA_MASK);
}
};
#endif /* MJClassInfo_h */
----------------------main.mm---------------------
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "MJClassInfo.h"
// MJPerson
@interface MJPerson : NSObject <NSCopying>
{
@public
int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end
@implementation MJPerson
- (void)test
{
}
- (void)personInstanceMethod
{
}
+ (void)personClassMethod
{
}
- (id)copyWithZone:(NSZone *)zone
{
return nil;
}
@end
// MJStudent
@interface MJStudent : MJPerson <NSCoding>
{
@public
int _weight;
}
@property (nonatomic, assign) int height;
- (void)studentInstanceMethod;
+ (void)studentClassMethod;
@end
@implementation MJStudent
- (void)test
{
}
- (void)studentInstanceMethod
{
}
+ (void)studentClassMethod
{
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
return nil;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MJStudent *stu = [[MJStudent alloc] init];
stu->_weight = 10;
mj_objc_class *studentClass = (__bridge mj_objc_class *)([MJStudent class]);
mj_objc_class *personClass = (__bridge mj_objc_class *)([MJPerson class]);
class_rw_t *studentClassData = studentClass->data();
class_rw_t *personClassData = personClass->data();
class_rw_t *studentMetaClassData = studentClass->metaClass()->data();
class_rw_t *personMetaClassData = personClass->metaClass()->data();
NSLog(@"1111");
}
return 0;
}
面试题
![](https://img.haomeiwen.com/i6434429/df543cabc6aac851.png)
网友评论