Objective-C中的 __weak 和 weak 是什么 ?

复制代码
          _____                    _____                    _____                    _____          
         /\    \                  /\    \                  /\    \                  /\    \         
        /::\____\                /::\    \                /::\    \                /::\____\        
       /:::/    /               /::::\    \              /::::\    \              /:::/    /        
      /:::/   _/___            /::::::\    \            /::::::\    \            /:::/    /         
     /:::/   /\    \          /:::/\:::\    \          /:::/\:::\    \          /:::/    /          
    /:::/   /::\____\        /:::/__\:::\    \        /:::/__\:::\    \        /:::/____/           
   /:::/   /:::/    /       /::::\   \:::\    \      /::::\   \:::\    \      /::::\    \           
  /:::/   /:::/   _/___    /::::::\   \:::\    \    /::::::\   \:::\    \    /::::::\____\________  
 /:::/___/:::/   /\    \  /:::/\:::\   \:::\    \  /:::/\:::\   \:::\    \  /:::/\:::::::::::\    \ 
|:::|   /:::/   /::\____\/:::/__\:::\   \:::\____\/:::/  \:::\   \:::\____\/:::/  |:::::::::::\____\
|:::|__/:::/   /:::/    /\:::\   \:::\   \::/    /\::/    \:::\  /:::/    /\::/   |::|~~~|~~~~~     
 \:::\/:::/   /:::/    /  \:::\   \:::\   \/____/  \/____/ \:::\/:::/    /  \/____|::|   |          
  \::::::/   /:::/    /    \:::\   \:::\    \               \::::::/    /         |::|   |          
   \::::/___/:::/    /      \:::\   \:::\____\               \::::/    /          |::|   |          
    \:::\__/:::/    /        \:::\   \::/    /               /:::/    /           |::|   |          
     \::::::::/    /          \:::\   \/____/               /:::/    /            |::|   |          
      \::::::/    /            \:::\    \                  /:::/    /             |::|   |          
       \::::/    /              \:::\____\                /:::/    /              \::|   |          
        \::/____/                \::/    /                \::/    /                \:|   |          
         sqi出品                  \/____/                  \/____/                  \|___|          

在 Objective-C 中,weak__weak 都与 ARC(Automatic Reference Counting,自动引用计数)相关,并且它们用于描述对象的弱引用。但是,它们在语法和上下文中有一些微妙的差异。

  1. weak:

    • weak 是属性修饰符,用于在类接口(.h.m 文件的类扩展中)中声明属性。
    • 当一个对象被声明为 weak 属性时,它不会增加对象的引用计数。这意味着当没有其他强引用指向该对象时,该对象可以被安全地释放,而无需担心循环引用。
    • 使用 weak 的常见场景是在代理(delegate)或回调闭包(block)中,以避免循环引用。
    • 示例:
    objective-c 复制代码
    @property (nonatomic, weak) id<SQIProtocol> delegate;
        @property (nonatomic, weak) SQICallback callback;
  2. __weak:

    • __weak是类型修饰符,用于声明对象的弱引用。
    • 示例:
    objective-c 复制代码
    __weak SQIClass *weakVariable = someObject;
    • 在 block 中,如果你需要捕获一个外部对象, 同时要避免循环引用,你应该使用 __weak 来声明一个弱引用,并在 block 内部使用它。
    • 如果该外部对象可能在 block 的生命周期内被释放,但你希望确保在访问它之前它仍然有效时,可以使用 __strong 来临时持有强引用(在 block 或方法内部)。这通常被称为"弱-强舞蹈"(weak-strong dance)。
    • 示例:
    objc 复制代码
    @interface MyObject : NSObject  
    
    - (void)performBlockOperation;  
    
    @end  
    
    @implementation MyObject  
    
    - (void)performBlockOperation {  
    	// 使用 __weak 创建一个对 self 的弱引用  
    	__weak MyObject *weakSelf = self;  
      
    	// 创建一个 block,并在其中执行一些操作  
    	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {  
        	// 在 block 内部,使用 weakSelf 可能会遇到它已经被释放的情况  
        	// 因此,我们使用一个局部强引用来确保对象在 block 执行期间存在  
        	MyObject *strongSelf = weakSelf;  
        	if (strongSelf) {  
            	// 现在我们可以安全地使用 strongSelf,因为即使 self 在其他地方被释放,  
            	// 在这个 block 执行期间,strongSelf 仍然指向它  
            	// 执行一些操作...  
                NSLog(@"Performing operation on %@", strongSelf);  
              
            	// 假设我们有一个 completion block,并且我们想在完成后调用它  
            	// 我们同样需要确保在调用它时 strongSelf 仍然存在  
            	dispatch_async(dispatch_get_main_queue()) {  
                	if (strongSelf) {  
                    	// 在主线程上执行完成操作...  
                    	NSLog(@"Operation completed on %@", strongSelf);  
                	}  
            	};  
        	}  
    	};  
    }  
    
    @end
  3. 共同点

    • 都不能用于非 Objective-C 对象(如 C 结构或 C++ 对象),因为 ARC 仅管理 Objective-C 对象的生命周期。
    • 都不会增加对象的引用计数, 当对象的引用计数变为零时,对象将被释放,而弱引用将自动被置为 nil。
相关推荐
2501_916008891 天前
iOS 证书管理最佳实践 从创建到续期的完整指南
android·ios·小程序·https·uni-app·iphone·webview
黑科技iOS上架2 天前
ReactNative入门介绍
经验分享·ios
智塑未来2 天前
鸿蒙系统对比安卓、iOS,核心优势是什么?
android·ios·harmonyos
初雪云2 天前
iOS 上架入门:证书、描述文件、IPA 上传到底是什么关系?
android·ios·自动化·产品经理·iphone
狂热开发者2 天前
用 Typeoff 把会后口述整理成 Markdown 决策记录
人工智能·windows·macos·ios·安卓
2501_916007472 天前
iPad 怎么抓包 从代理模式到暴力抓包的操作方法
android·ios·小程序·uni-app·代理模式·iphone·ipad
2501_915918412 天前
PerfDog 太贵?iOS 性能监控工具的功能对比与选择
android·ios·小程序·https·uni-app·iphone·webview
MDM.Plus3 天前
苹果MDM技术演进:从远程控制到设备信任体系的构建
运维·服务器·安全·ios·mdm·手机店
韩曙亮3 天前
【Flutter】Flutter 进程保活 ③ ( 屏幕常亮设置 | Flutter 禁止息屏、关闭自动锁屏、屏蔽系统屏保 )
android·flutter·ios·屏幕常亮·禁止息屏
2501_915909063 天前
IPA 深度混淆是什么意思?从混淆强度到实际效果的解读
android·ios·小程序·https·uni-app·iphone·webview