美文网首页
一句话笔记(41)(自动释放词)

一句话笔记(41)(自动释放词)

作者: 天空中的球 | 来源:发表于2020-04-29 22:21 被阅读0次

    一句话笔记,某段时间内遇到或看到的某个可记录的点。

    • 1、自动释放词的理解
    • 2、怎样实现一个精确的 NSTimer ?
    • 3、如何防止拦截潜在的崩溃?

    一、自动释放词的理解

    可以先想想自动释放词的理解和印象

    • 概念
      AutoreleasePool(自动释放池)是OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release的时机。在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行。
    • AtAutoreleasePoolAutoreleasePoolPage
      AtAutoreleasePool 调用函数
    AutoreleasePoolPage 结构,所有的AutoreleasePoolPage对象通过双向链表的形式连接在一起
    • 每执行@autoreleasepool底层对应执行objc_autoreleasePoolPush(); 就会往AutoreleasePoolPage添加POOL_BOUNDARY,并返回POOL_BOUNDARY所在AutoreleasePoolPage的内存空间地址

    • @autoreleasepool{}大括号结束 内部创建的__AtAutoreleasePool对象销毁,调用析构函数objc_autoreleasePoolPop(atautoreleasepoolobj);

    • AutoreleasePoolPage开始从后往前遍历autorelease对象调用release方法直到objc_autoreleasePoolPop()传入的POOL_BOUNDARY地址为止

    • 自动释放池在mrc和arc区别:

      • ARC下除了NSAutoreleasePool不可用以外,其他相同
    • Autorelease对象什么时候释放?
      在没有手加Autorelease Pool的情况下,Autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池PushPop
    iOS程序运行 在主线程中注册了2个Observer 分别监听RunLoop
    第一个Observer监听了kCFRunLoopEntry 会调用objc_autoreleasePoolPush
    第二个Observer监听了kCFRunLoopBeforeWaiting 会调用objc_autoreleasePoolPop
    

    笔记来源: iOS进阶四-自动释放池原理iOS 自动释放池ARC与MRC

    二、怎样实现一个精确的NSTimer?

    2.1不准的原因如下:
    • NSTimer 加在 main Runloop 中,模式是NSDefaultRunLoopModemain负责所有主线程事件,例如UI界面的操作,复杂的运算,这样在同一个Runlooptimer就会产生阻塞。

    • 模式的可能改变。主线程的 RunLoop 里有两个预置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode, 切换时需要退出和进入可能导致时间的不准。

    2.2 解决的方案:
    • 子线程中创建 NSTimer, 在子线程中进行定时任务的操作,需要UI操作时切换回主线程进行操作 。
    • 对于模式的影响,直接将 NSTimer 的 mode 更换成 NSRunLoopCommonModes
    • 转换用 GCD 的计时器,dispatch_source_t。

    三、 如何防止拦截潜在的崩溃

    1、利用 Runtime方法交换技术,将系统方法替换成类添加的新方法。

    • 类似 消息转发中,可能出现的问题,进行交换
    • 类似数组越界的判断
    • 类似字典,字符串 为空的

    具体可以看 NSObjectSafe 的处理,其中一个如下

    + (void)load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            swizzleInstanceMethod([NSObject class], @selector(addObserver:forKeyPath:options:context:), @selector(hookAddObserver:forKeyPath:options:context:));
            swizzleInstanceMethod([NSObject class], @selector(removeObserver:forKeyPath:), @selector(hookRemoveObserver:forKeyPath:));
            swizzleInstanceMethod([NSObject class], @selector(methodSignatureForSelector:), @selector(hookMethodSignatureForSelector:));
            swizzleInstanceMethod([NSObject class], @selector(forwardInvocation:), @selector(hookForwardInvocation:));
        });
    }
    

    2、利用异常的捕获来防止程序的崩溃,并且进行相应的处理。

    @try {
        // 可能会出现崩溃的代码
    }
    @catch (NSException *exception) {
        // 捕获到的异常exception
    }
    @finally {
        // 结果处理
    }
    

    相关文章

      网友评论

          本文标题:一句话笔记(41)(自动释放词)

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