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。
相关推荐
tiantian_cool4 小时前
Claude Code 四大核心技能使用指南
ios
冰淇淋真好吃8 小时前
iOS实现 WKWebView 长截图的优雅方案
ios
TG_imqfxt66612 小时前
虚拟机下安装苹果系统,虚拟机下如何实现协议群发iMessage?
python·objective-c
前端不太难13 小时前
Flutter / RN / iOS,在长期维护下的性能差异本质
flutter·ios
搜狐技术产品小编20231 天前
精通 UITableViewDiffableDataSource——从入门到重构的现代 iOS 列表开发指南
ios·重构
tangweiguo030519872 天前
SwiftUI 状态管理完全指南:从 @State 到 @EnvironmentObject
ios
声网2 天前
如何用 Fun-ASR-Nano 微调一个「听懂行话」的语音模型?丨Voice Agent 学习笔记
笔记·学习·xcode
Digitally2 天前
如何轻松地将文件从 PC 传输到 iPhone
ios·iphone
iosTiov2 天前
当IPA遇见信任:解密ios生态中“签名”的真正力量
ios·团队开发·苹果签名·稳定
TheNextByte12 天前
如何将 iMessage 保存到外部硬盘驱动器
macos·objective-c·cocoa