美文网首页iOS开发你需要知道的
iOS-面试题 内存管理(夯实基础学习笔记-温故知新5)

iOS-面试题 内存管理(夯实基础学习笔记-温故知新5)

作者: 朱允见 | 来源:发表于2020-07-02 11:11 被阅读0次
    1. 使用CADisplayLink、NSTimer有什么注意点?

    2. 介绍下内存的几大区域

    3. 讲一下你对 iOS 内存管理的理解

    4. ARC 都帮我们做了什么?
      LLVM + Runtime

    5. weak指针的实现原理

    6. autorelease对象在什么时机会被调用release

    7. 方法里有局部对象, 出了方法后会立即释放吗


    image.png

    NSTimer依赖于RunLoop,如果RunLoop的任务过于繁重,可能会导致NSTimer不准时
    而GCD的定时器会更加准时

    + (NSString *)execTask:(void (^)(void))task start:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats async:(BOOL)async
    {
        if (!task || start < 0 || (interval <= 0 && repeats)) return nil;
        
        // 队列
        dispatch_queue_t queue = async ? dispatch_get_global_queue(0, 0) : dispatch_get_main_queue();
        
        // 创建定时器
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        
        // 设置时间
        dispatch_source_set_timer(timer,
                                  dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC),
                                  interval * NSEC_PER_SEC, 0);
        
        
        dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_FOREVER);
        // 定时器的唯一标识
        NSString *name = [NSString stringWithFormat:@"%zd", timers_.count];
        // 存放到字典中
        timers_[name] = timer;
        dispatch_semaphore_signal(semaphore_);
        
        // 设置回调
        dispatch_source_set_event_handler(timer, ^{
            task();
            
            if (!repeats) { // 不重复的任务
                [self cancelTask:name];
            }
        });
        
        // 启动定时器
        dispatch_resume(timer);
        
        return name;
    }
    
    
    image.png
    Tagged Pointer
    • 从64bit开始,iOS引入了Tagged Pointer技术,用于优化NSNumber、NSDate、NSString等小对象的存储

    • 在没有使用Tagged Pointer之前, NSNumber等对象需要动态分配内存、维护引用计数等,NSNumber指针存储的是堆中NSNumber对象的地址值

    • 使用Tagged Pointer之后,NSNumber指针里面存储的数据变成了:Tag + Data,也就是将数据直接存储在了指针中

    • 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据

    • objc_msgSend能识别Tagged Pointer,比如NSNumber的intValue方法,直接从指针提取数据,节省了以前的调用开销

    • 如何判断一个指针是否为Tagged Pointer?
      iOS平台,最高有效位是1(第64bit)
      Mac平台,最低有效位是1

    image.png
    OC对象的内存管理

    在iOS中,使用引用计数来管理OC对象的内存

    一个新创建的OC对象引用计数默认是1,当引用计数减为0,OC对象就会销毁,释放其占用的内存空间

    调用retain会让OC对象的引用计数+1,调用release会让OC对象的引用计数-1

    内存管理的经验总结
    当调用alloc、new、copy、mutableCopy方法返回了一个对象,在不需要这个对象时,要调用release或者autorelease来释放它
    想拥有某个对象,就让它的引用计数+1;不想再拥有某个对象,就让它的引用计数-1

    可以通过以下私有函数来查看自动释放池的情况
    extern void _objc_autoreleasePoolPrint(void);


    image.png image.png image.png image.png image.png image.png image.png

    相关文章

      网友评论

        本文标题:iOS-面试题 内存管理(夯实基础学习笔记-温故知新5)

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