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_915918416 小时前
Fiddler中文版全面评测:功能亮点、使用场景与中文网资源整合指南
android·ios·小程序·https·uni-app·iphone·webview
不知名It水手8 小时前
uniapp运行项目到ios基座
ios·uni-app·cocoa
Digitally9 小时前
[5种方法] 如何将iPhone短信保存到电脑
ios·iphone
杂雾无尘12 小时前
Swift 5.9 新特性揭秘:非复制类型的安全与高效
ios·swift·apple
Thomas_YXQ15 小时前
Unity3D iOS闪退问题解决方案
ios
Daniel_Coder18 小时前
iOS Widget 开发-7:TimelineProvider 机制全解析:构建未来时间线
ios·swift·widget
Daniel_Coder19 小时前
iOS Widget 开发-3:Widget 的种类与尺寸(主屏、锁屏、灵动岛)
ios·swift·widget
Engandend1 天前
Flutter与iOS混合开发交互
flutter·ios·程序员
山水域2 天前
GoogleAdsOnDeviceConversion 库的作用与用法
ios
Lucifer晓2 天前
记录一次Flutter项目上传App Store Connect出现“Validation failed”错误的问题
flutter·ios