weak_clear_no_lock 报错处理

博客详细描述了一个iOS应用上线后遇到的weak_clear_no_lock异常问题。问题源于登录页面在dismiss后尝试设置WKWebView的UIDelegate,而此时页面正在释放。解决方案包括在dismiss后再回调登录成功block或者在dealloc时避免使用点语法设置代理。

项目上线之后,通过firbase追踪发现有一个异常报错,闪退率惊人,起初我们以为是firebase同步了WKWebView的异常信息导致的,但后来在本人手机上复测发现实际上不是这个问题,是真正Bug存在。

Crashed: com.apple.main-thread
0  libsystem_kernel.dylib         0x1af90d858 __abort_with_payload + 8
1  libsystem_kernel.dylib         0x1af911ed8 abort_with_payload_wrapper_internal + 104
2  libsystem_kernel.dylib         0x1af911e70 abort_with_payload_wrapper_internal + 30
3  libobjc.A.dylib                0x1af85a3cc _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 108
4  libobjc.A.dylib                0x1af85a360 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30
5  libobjc.A.dylib                0x1af856530 weak_clear_no_lock + 322
6  libobjc.A.dylib                0x1af857f70 objc_storeWeak + 336
7  WebKit                         0x1b743d5b0 WebKit::UIDelegate::setDelegate(id<WKUIDelegate>) + 32
8  WebKit                         0x1b71d2acc -[WKWebView setUIDelegate:] + 48
### `weak_ptr.lock` 的功能与作用 `weak_ptr.lock` 是 C++ 标准库中 `std::weak_ptr` 类的一个成员函数,其主要作用是将 `weak_ptr` 临时升级为 `std::shared_ptr`,从而安全地访问其观察的对象。该函数会检查当前 `weak_ptr` 所指向的对象是否仍然有效(即是否已被释放)。如果对象仍然存在,则 `lock` 返回一个指向该对象的 `shared_ptr`;如果对象已被释放,则返回一个空的 `shared_ptr` [^3]。 这种机制可以确保在访问对象时,其生命周期不会被意外终止,因为返回的 `shared_ptr` 会增加对象的引用计数,直到该 `shared_ptr` 被销毁或重置。这种方式有效避免了多线程环境下对象被提前释放的问题。 ### 使用示例 以下是一个使用 `weak_ptr.lock` 的示例: ```cpp #include <iostream> #include <memory> int main() { std::shared_ptr<int> shared = std::make_shared<int>(42); std::weak_ptr<int> weak = shared; // 使用 lock() 检查对象是否存在 if (std::shared_ptr<int> lockedPtr = weak.lock()) { std::cout << "对象仍然存在,值为: " << *lockedPtr << std::endl; } else { std::cout << "对象已被释放。" << std::endl; } // 释放 shared_ptr shared.reset(); // 再次尝试访问对象 if (std::shared_ptr<int> lockedPtr = weak.lock()) { std::cout << "对象仍然存在,值为: " << *lockedPtr << std::endl; } else { std::cout << "对象已被释放。" << std::endl; } return 0; } ``` 在上述代码中,第一次调用 `weak.lock()` 返回一个有效的 `shared_ptr`,并输出对象的值;而在 `shared_ptr` 被释放后,再次调用 `weak.lock()` 将返回空指针,表明对象已经被销毁 [^3]。 ### 注意事项 - `lock` 方法返回的 `shared_ptr` 是临时的,仅在该 `shared_ptr` 实例存在期间延长对象的生命周期。 - 在多线程环境中,`lock` 操作是线程安全的,多个线程可以同时调用 `lock` 而不会导致数据竞争问题 [^2]。 - 使用 `lock` 之前,可以通过 `expired` 方法检查对象是否已经释放,以避免不必要的操作。 ### 相关问题 1. 如何在 C++ 中使用 `std::weak_ptr` 来管理资源? 2. `std::shared_ptr` 和 `std::weak_ptr` 的区别是什么? 3. 如何避免 C++ 中智能指针导致的循环引用问题? 4. `std::weak_ptr` 在多线程环境下的线程安全性如何保障? 5. `std::weak_ptr` 的典型应用场景有哪些?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值