iOS 杂记

真机上如何实现模拟器"Slow Animation"的效果?

  • 利用lldb,断点后执行以下命令即可 p [(CALayer *)[[[[UIApplication sharedApplication] windows] objectAtIndex:0] layer] setSpeed:.1f]
日志文件中包含太多[32m、[0m 这样的字符,影响查看怎么办?
  • 这其实是终端的一种用于表示颜色的编码,可以使用 less log_path 命令来查看日志,可以正常显示出相应的颜色。
  • cat到terminal查看,还可以看到颜色
Xcode code snippet 如何能云同步呢?
  • Xcode中的代码片段默认放在这个目录中: ~/Library/Developer/Xcode/UserData/CodeSnippets 创建一个git repo,设置链接,就可以轻松使用git管理了
私有对象,使用成员变量定义,还是preporty定义?
  • 现在项目中只有很少的一部分老代码使用了成员变量,现在开发基本都是property,property会自动生成一个对应的成员变量,同时合成getter setter方法 porperty 使用相对便捷,而且支持 getter 和 setter,成员变量相对成本更低一些,所以包大小会小一些,性能会好一点
  • 需要 lazy load 的话还是 property 更方便
  • 在 block 中传递和访问成员变量 Crash 的 case 经常发生
如何在runtime环境下,通过方法名来调用类的无参数静态方法? 如,ClassX,类方法名为 dummy,无参数无返回值。
  • 先通过NSSelectorFromString获取sel,再通过methodForSelector:获取sel对应的函数指针imp,将imp强转为函数,直接调用这个函数
  • 类似于 idle 或者刷新类的,一直调用的方法,可以直接写成函数,避开走消息转发可以提高效率和较少一丢丢二进制代码量
    NSMethodSignature *signature = [clz methodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setSelector:selector];
    [invocation setTarget:clz];
    [invocation setArgument:&model atIndex:2];
    [invocation setArgument:&trackContext atIndex:3];
    [invocation setArgument:&componentContext atIndex:4];
    [invocation invoke];
  • 用C语言的dlsym()方法可在内存中寻找"string_function"静态方法,并返回函数指针;判空后即可调用。
  • libffi了解一下
OC里的block为什么要判空后再调用?
  • 从原理上来说,每个 Block 都是一个 struct,内部有个 fn 指针,最终调用 block(xxx) 的时候实际是调用这个指针指向的函数,为空就崩了
  • block clang后是一个结构体,通过这个结构体去调用block实现的函数指针,不判空就是 NULL->funcPtr
  • oc里的block会被重写为一个结构体(类的结构),其中block中的代码块会被放在一个静态函数内,结构体的函数指针指向该静态方法。若block为空,此函数指针即为空,调用时就会引发EXC_BAD_ACCESS类型Crash
开发中我们如何快速定位内存泄漏问题?
  • 这里展示一种:打开Debug Memory Graph就可以具体查某个类的实例的当前持有者了,通过分析持有关系判断。其他参考:https://xibhe.com/2019/05/27/iOS%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%E6%A3%80%E6%B5%8B/
Xcode 使用lldb调试时遇到id指针时的属性访问方式
  • 在Xcode的lldb调试的时候对于id指针使用.表达式访问会提示找不到属性,这时可以通过消息进行调用,就可以正常输出或者执行了
  • 中括号是消息发送,不需要知道是什么类型;点语言点出对应的属性,需要知道是哪个类才可以索引出来
Xcode 实用快捷键,提高工作效率
  • ctrl+i 格式化代码
  • cmd + shift + o 快速查找
  • command+shift+j 快速定位到文件
  • control+command+r 跳过编译装上次编译好的包
  • control+command+向上箭头 在.m文件快速切换到.h文件
  • control+command+向下箭头 在.h文件快速切换到.m文件
如何给 UIView block 动画添加自定义时间函数
  • CATransaction,我先来个吧~
  • CAAnimation动画都可以通过设置timingFunction实现自定义的时间函数
  • 贝塞尔 + DisplayLink 可行不
  • 在UIView block外围用CATransaction包起来(begin, commit方法),调用CATransaction的类方法setAnimationTimingFunction。
property 中 copy 的意义?
  • https://juejin.cn/post/6844904033019232264
__block 解决了什么问题?
  • 修改block内引用变量的可变性,一般用于局部变量
静态库和动态库有什么主要区别?
  • 静态库在编译时链接到代码中,动态库在运行时载入;动态库能让库更好的复用~
  • 印象中 iOS 这边系统的动态库才是程序运行时由系统动态加载,由多个程序共享;我们自己写的动态库只能是 App 与 Extension 之间共享,并且要设置成 embedded framework 才能在 App 启动的时候加载到,否则就报 Image Not Found 错误了。所以其实我们自己写的动态库某种意义上也只是静态库罢了。
  • 细说iOS的静态库和动态库:https://juejin.im/post/6844904031937101838
  • 动态库只能依赖动态库,如果LiveKit改成动态库,那么它依赖的所有库都必须是动态库,改造成本太高。 对包大小没有明显收益,对宿主的启动速度有劣化风险。
给局部变量增加static关键字会产生什么影响?
  • 这个地方的局部变量值创建一次,并且不会被销毁,跟随整个app的生命周期
  • 不会改变作用域,但会改变生命周期;只会初始化一次,下次的使用的值基于上次的结果的值
  • 会存入data段
OC 协议能有默认实现吗?
  • ProtocolKit 能实现
  • 通过魔法....https://draveness.me/protocol-extension/
  • OC 协议本身是没有默认实现的,但是作为动态语言,通过 Runtim 可以实现协议的默认实现,下面给出 extobjc 中的实现:https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTConcreteProtocol.h
Category 中通过关联对象实现(getter,setter)的 property 通过 KVO可以监听其变化吗?原理?
  • 可以,kvo是动态偷偷的创建一个子类,重写监听对象的setter;所以分类的setter一样也可以被kvo监听到
  • 给 Category 的 property 添加 KVO 监听系统会在setter方法类似的调用 willChangeValueForKey: 与 didChangeValueForKey: 方法,具体实现较复杂,可以文档:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177-BCICJDHA
OC 中有哪些hook方法的姿势?

待补充

什么是离屏渲染?哪些情况下会触发离屏渲染?

待补充

为什么要对NSTimer进行一层封装?
  • 主要是防止忘了处理timer,导致循环引用
  • 这个问题的细节可以引申一下,中台的timer处理,为什么采用了block方式,没有采用https://juejin.im/post/6844903968250789896 里提到的proxy方式
    1. 解决target循环引用的问题;2. 屏蔽NSTimer和runloop的关系。
你遇到过哪些循环引用的case?
_reportTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(reportPlayingStatus) userInfo:nil repeats:YES]; (一不小心就会泄露..)
#define XLiveLinkInline(PROTOCOL) ((id)xLiveLinkInlineFunc(@protocol(PROTOCOL),self))   xlivelinkinline里是有self的,使用时需要注意
声明 block 的时候为什么使用copy,而不用strong?
  • arc 用这两效果都一样,block 赋值的时候默认就会被 copy 到堆上,声明的时候用 copy 可以显得自己懂得本质
    image.png
  • 使用copy是历史原因,在ARC中使用strong也是可以的。参考:https://stackoverflow.com/questions/27152580/cocoa-blocks-as-strong-pointers-vs-copy
什么是 Target-Action?你知道有哪些使用 Target-Action 的方式来响应事件?

待补充

如何看待在代码中频繁使用 #if DEBUG 这样的环境宏判断?

待补充

你可能感兴趣的:(iOS 杂记)