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。
相关推荐
Magnetic_h8 小时前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa
龙腾-虎跃9 小时前
FreeSWITCH FunASR语音识别模块
人工智能·语音识别·xcode
00后程序员张10 小时前
详细解析苹果iOS应用上架到App Store的完整步骤与指南
android·ios·小程序·https·uni-app·iphone·webview
前端小超超10 小时前
capacitor配置ios应用图标不同尺寸
ios·蓝桥杯·cocoa
2501_9151063212 小时前
Xcode 上传 ipa 全流程详解 App Store 上架流程、uni-app 生成 ipa 文件上传与审核指南
android·macos·ios·小程序·uni-app·iphone·xcode
kymjs张涛14 小时前
零一开源|前沿技术周刊 #16
ios·apple·hacker news
2301_8210465214 小时前
Python与Go结合
ios·iphone
他们都不看好你,偏偏你最不争气15 小时前
【iOS】AFNetworking
开发语言·macos·ios·objective-c
zhanggui17 小时前
iOS Debug Symbols
ios·xcode·debug symbox
钟念18 小时前
【打包app】uniapp打包ios端和安卓端app
macos·objective-c·cocoa