[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fcoGm1XVOxrwBKCVMeizaNueSiydRT9OAj3zZ43fOVaw":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":12,"notice":12,"visitCount":28,"commentCount":29,"keywords":30},38,"2024-01-30T03:58:16.359Z","runtime-对象和方法","1.  OC对象的本质 -> 结构体\n\noc文件->.cpp文件:\n\n    clang -rewrite-objc main.m -o main.cpp\n\n*   完整命令：\n\n\u003C!---->\n\n    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.c++\n\n1.  方法的本质 -> 消息发送\n    objc:\n\n\u003C!---->\n\n    - (void)run { }\n\n对应底层C:\n\n    void run(id self, SEL _cmd) { }\n\n1.  方法： 对象方法和类方法.\n\n2.  runtime的调用方式：三种：\n\n*   runtime api: class\\_get...\n*   NSObject api: isKindOf isMemberOf\n*   oc上层方法: @selector\n\n1.  对象方法的调用：\n\n\u003C!---->\n\n    Object *obj = [Object new];\n    [obj run];\n\n*   [x] 方法调用的底层编译\n*   [x] 方法的本质： 消息： 消息接受者 消息编号 ...参数（消息体）\n\n\u003C!---->\n\n    objc_msgSend(obj, sel_registerName(\"run\"));\n\n1.  类方法编译底层\n\n\u003C!---->\n\n    id cls = [ObjectClass class];\n    void *pointA = &cls;\n    [(__bridge id)pointA walk];\n\n\\===\n\n    objc_msgSend(objc_getClass(\"ObjectClass\"), sel_registerName(\"walk\"));\n\n*   向父类发消息（对象方法）:\n\n\u003C!---->\n\n    struct objc_super mySuper;\n    mySuper.receiver = obj;\n    mySuper.super_class = class_getSuperclass([obj class);\n    objc_msgSendSuper(&mySuper, @selector(run));\n\n*   向父类发消息（类方法）：\n\n\u003C!---->\n\n    struct objc_super myClassSuper;\n    myClassSuper.receiver = [obj class];\n    myClassSuper.super_class = class_getSuperClass(object_getClass([obj class])); // 元类\n    objc_msgSendSuper(&myClassSuper, sel_registerName(\"walk\"));\n\n1.  对象方法存在类中\n\n2.  类方法存在元类中\n\n3.  类方法在元类中，以什么样的姿态存在？\\\n    ：以实例方法存在.\n\n4.  对象在类中是以实例存在.\n\n5.  类在元类中也是以实例形式存在.\n\n6.  objc\\_msgSend\n    两种方式：\n\n*   快速 by汇编 缓存找 cache\\_t imp 哈希表\n*   慢速 c, c++一起完成，找到存缓存\n\n否则 经过复杂的过程 \\\n为什么使用汇编写？\n\n*   c 写一个函数，不可能保留未知的参数，跳转到任意的指针.\n*   块，c还要向下编译\n*   汇编可以保存，by 寄存器 x0 x31\n\n1.  源码分析流程\n\n*   汇编部分\n*   c,c++部分 \\\n    具体查看 opensource.apple.com -> objc4 \\\n    分析源码的文件是objc4中arm64相关的.s汇编文件，然后汇编中有`__class_lookupMethodAndLoadCache3`一个宏调用，要在工程中使用`_class_lookupMethodAndLoadCache3`来查找，因为在.mm文件里面.\n\n大概的过程：\n\n*   消息发送调用后，通过汇编，从汇编的缓存中查找\n*   如果找到，那么就直接调用，否则查找方法实现的函数指针，找到实现函数指针，就返回函数指针\n*   如果在缓存中找不到，也找不到函数指针，那么通过c、c++函数去找，先是自己的类中找，然后递归从父类中查找。\n*   如果找到，那么就fill cache并且返回这个函数指针。找不到的话，那么就要开始走动态解析了。\n\n\\-- Warning:\n在c、c++的查找过程中，会再次判断一下缓存中是否有函数实现，尽管汇编过程中已经判断过缓存。这个原因是：oc语言的动态性，并发，有可能使缓存中有值了。\n\n1.  动态方法解析.\n    类的方法解析：（动态方法解析的函数名一样，只是前缀是-，而不是+）\n\n\u003C!---->\n\n    + (BOOL)resolveInstanceMethod:(SEL)sel {\n        return [super resolveinstanceMethod: sel];\n    }\n\n\u003C!---->\n\n    + (BOOL)resolveClassMethod:(SEL)sel {\n        return [super resolveClassMethod: sel];\n    }\n\n","runtime中关于对象和方法的本质，以及如何去验证和理解其中的原理。","",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",3,{"id":24,"name":26,"parentId":21},"iOS",[],58,0,"objective-c,ios runtime,swit runtime,oc runtime"]