qiniu / objc-sdk

Qiniu Resource (Cloud) Storage Objective-C SDK for Mac/iOS
http://developer.qiniu.com
MIT License
435 stars 197 forks source link

fix over-release issue about Token and Hosts of QNServerConfigSynchro… #425

Open lyandy opened 1 year ago

lyandy commented 1 year ago

sentry crash stacks: https://app-sentry.taou.com/share/issue/8c4977e7073c4e0996b1248f93025c37 ref: https://github.com/qiniu/objc-sdk/issues/423

YangSen-qn commented 1 year ago

@lyandy 读写都需要加锁,感谢您的 pr

lyandy commented 1 year ago

@lyandy 读写都需要加锁,感谢您的 pr

考虑过 也加锁,但相比 造成 over-release的概率更高些。并且发生 ref: https://github.com/qiniu/objc-sdk/issues/423 高频崩溃也是


理论上 读写 都要加锁会更安全些。但仔细分析即使 读写 都加锁 也不能完全避免多线程野指针问题。

举个例子, Token的时候使用锁, 到的值是A,当时没问题。可能 到的值不会立刻用。在很短的时间内Token又被 成了B。

我真正要用最初 到的A值时,A就变成了野指针。


如果要彻底解决多线程安全问题,就要在所有用到 读写 Token的地方加锁,但这势必会造成一定的性能损失。


综上,针对 ref: https://github.com/qiniu/objc-sdk/issues/423 高频崩溃,我提的PR足以解决此问题

YangSen-qn commented 1 year ago

@lyandy 读写都需要加锁,感谢您的 pr

考虑过 也加锁,但相比 造成 over-release的概率更高些。并且发生 ref: #423 高频崩溃也是

理论上 读写 都要加锁会更安全些。但仔细分析即使 读写 都加锁 也不能完全避免多线程野指针问题。

举个例子, Token的时候使用锁, 到的值是A,当时没问题。可能 到的值不会立刻用。在很短的时间内Token又被 成了B。

我真正要用最初 到的A值时,A就变成了野指针。

如果要彻底解决多线程安全问题,就要在所有用到 读写 Token的地方加锁,但这势必会造成一定的性能损失。

综上,针对 ref: #423 高频崩溃,我提的PR足以解决此问题

这里讨论的 野指针(这里说悬空指针更合适些)的原因是新的 Token 被赋值,在 ARC 中此处 OC 对象会被自动添加 CFRealese (这也是造成 over-release 的原因),可能会导致 OC 对象已经被释放但是指针仍是旧值的情况,也就出现了所谓的 野指针 ; 如果加上读写锁就会保证 Token 在读写时指针均指向有效空间,在使用时有临时变量指向了这份空间,也就会使引用计数 +1 ,对象也就不会被释放,所以加了读写锁后也就不会出现所谓的 野指针。另外,我们一般处理时会选择 copy , 这样使用的对象和 Token 对象不是同一个。