美文网首页
iOS - 学习笔记 - OC对象

iOS - 学习笔记 - OC对象

作者: GA_ | 来源:发表于2020-06-12 13:44 被阅读0次
    // 实例对象
    NSObject *object1 = [[NSObject alloc] init];
    NSObject *object2 = [[NSObject alloc] init];
    
    // 类对象
    Class objcetClass1 = [object1 class];
    Class objcetClass2 = [object2 class];
    Class objectClass3 = [NSObject class];
    Class objectClass4 = object_getClass(object1);
    Class objectClass5 = object_getClass(object2);
    
    // 元类对象
    Class objectTetaClass1 = object_getClass([NSObject class]);
    Class objectTetaClass2 = object_getClass(objcetClass1);
    
    instance对象 实例对象
        通过类alloc出来的对象,每次alloc都会产生新的instance对象,占据不同的内存
        实例对象内存中只存储成员变量、isa指针
        isa指针地址就是instance对象的地址
    class对象 类对象
        一个类的类对象在内存中只有一个
        objcetClass1、objcetClass2、objcetClass3、objcetClass4、objcetClass5指向的指针是同一个
        类对象在内存中存储isa指针、superclass指针、属性信息、对象方法信息、协议信息、类的成员变量信息
    meta-class对象 元类对象
        元类对象也是Class类型
        isa、superclass、类方法
        和类对象内存结构是一样的。
        class_isMetaClass 判断是否是元类
        object_getClass传类对象
    
    • NSObject对象占用多少内存
    NSObject *obj = [[NSObject alloc] init];
    
    16字节
    
    • Objective-C代码
    Objective-C -> c\c++ -> 汇编语言(依赖硬件) -> 机器语言
    Objective-C面向对象都是基于c\c++实现的
    
    Objective-C对象基于什么数据结构实现?
        结构体(容纳不同类型)
    
    //
    //  main.m
    //  OC_Object
    //
    //  Created by houjianan on 2020/6/10.
    //  Copyright © 2020 houjianan. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            NSObject *obj = [[NSObject alloc] init];
        }
        return 0;
    }
    
    • OC如何转成c\c++
    clang 
    clang -rewrite-objc main.m -o main.cpp
        cpp:c plus plus
    
    xcrun
    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
        -sdk iphoneos:指定是iphoneos
        clang -arch arm64:编译器指定架构
        -rewrite-objc main.m -o main-arm64.cpp:重写main.m文件输出为 main-arm64.cpp
    
    • 查看main-arm64.cpp
    // NSObject定义
    @interfaction NSObject {
        Class isa;
    }
    @end 
    
    // 底层实现
    struct NSObect_IMPL {
        Class isa; // 指针 类型是Class 指针在64位环境占8字节 在32位占4字节
    }
    
        isa内存地址赋值给obj isa的内存地址就是这个结构体的地址(就是第一个成员的地址)
    
    • 实例对象
    获得NSObject类的实例对象的成员变量所占用的大小
    NSLog(@"%zd", class_getInstanceSize([NSObject class]));
    —> 8
    
    NSLog(@"%zd", sizeof([[Person alloc] init]));
    —> 8
    
    获取obj指针所指向内存的大小
    #import <malloc/malloc.h>
    NSObject *obj = [[NSObject alloc] init];
    NSLog(@"%zd", malloc_size((__bridge const void *)obj));
    —> 16
    
    • 源码
    size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size =16;
        return size;
    }
    
    • Debug -> Debug Workfllow -> View Memory
      输入内存地址 查看内存

    • Student对象 16字节

    • 前8字节放isa

    • 后8字节放_no和_age

    @interface Student: NSObject 
    {
        @public 
        int _no;
        int _age;
    }
    @end 
    
    @implementation Student 
    
    @end 
    
    int main(int argc, onst char * argv[]) {
        @autoreleasepool {
            Student *s = [[Student alloc] init];
            s->_no = 4;
            s->_age = 5;
    
            stuct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)stu;
            NSLog(@"no is %d, age is %d", stuImpl->_no, stuImpl->_age);
        }
    }
    
    • .cpp中
    struct Student_IMPL {
        struct NSObject_IMPL NSObject_IVARS; 
        int _no;
        int _age;
    }
    
    struct NSObject_IMPL NSObject_IVARS;
        父类结构
        相当于    Class isa; // 8字节 alloc了16字节 使用8字节
    int _no;
    int _age;
        自己的成员变量
    
    struct NSObect_IMPL {
        Class isa;
    }
    
    • calloc
    void* calloc(size_t num_items, size_t size) {
        void *retval;
        retval = malloc_zone_calloc(default_zone, num_items, size);
        if (retval == NULL) {
            errno = ENOMEM;
        }
        return retval;
    }
    
    • tips
    1、指针在64位环境占8字节 在32位占4字节
    2、impl缩写implementation:实现
    3、armv7 arm32 arm64等等架构
    4、没有指定架构导出来的cpp文件比指定架构的大
    5、oc对象在底层就是一个结构体
    6、具体占多少字节 跟平台有关系
    7、结构体的内存地址就是第一个成员的地址
    8、(__bridge const void *) oc和c\c++桥接
    9、https://opensource.app.com/tarballs 苹果源码地址
    10、int _no 4字节 double 8字节
    11、大端、小端。iOS中是小端
    12、结构体内存对齐(有利于CPU访问)
    13、gnu开源组织
    14、sizeof是运算符,编译期已经确定。
    15、class方法 返回的是类对象([NSObject class])
    16、object_getClass传类对象
    

    相关文章

      网友评论

          本文标题:iOS - 学习笔记 - OC对象

          本文链接:https://www.haomeiwen.com/subject/kmvgtktx.html