强引用和弱引用

关于强引用和弱引用

__weak 和 __strong 会出现在声明中

默认情况下,一个指针都会使用 __strong 属性,表明这是一个强引用。这意味着,只要引用存在,对象就不能被销毁。这是一种所期望的行为:当所有(强)引用都去除时,对象才能被收集和释放。

不过, 有时我们却希望禁用这种行为:一些集合类不应该增加其元素的引用,因为这会引起对象无法释放。在这种情况下,我们需要使用弱引用(不用担心,内置的集合类 就是这么干的),使用 __weak 关键字。NSHashTable 就是一个例子。当被引用的对象消失时,弱引用会自动设置为 nil。Cocoa 的 Notification Center 就是这么一个例子,虽然这已经超出纯 Objective-C 的语言范畴

1.(weak与strong)不同的是:当一个对象不再有strong类型的指针指向它的时候,它就会被释放,即使改对象还有_weak类型的指针指向它;

2.一旦最后一个指向该对象的strong类型的指针离开,这个对象将被释放,如果这个时候还有weak指针指向该对象,则会清除掉所有剩余的weak指针

形象化理解: 一个对象类比为结婚证,释放对象类比为离婚.

__strong相当于结婚证,无论这两个人感情如何,他们在在结婚证上存在牵绊,那么他们就是夫妻,如果他们离婚,那么他们就不再是夫妻关系.(当然,有些国家是可以一夫多妻的:D)

__weak相当于约炮,不管你约再怎么约,约多少个都不能成立夫妻关系.


只要最后一个strong型指针不再指向对象,那么对象就会被释放,同时所有的weak型指针都将会被清除。
在OC中strong就相当于retain属性,而weak相当于assign。只有一种情况你需要使用weak(默认是strong),就是为了避免retain cycles(就是父类中含有  子类{父类retain了子类},子类中又调用了父类{子类又retain了父类},这样都无法release)

<think>嗯,用户问的是强引用弱引用是什么意思。之前他们问过C#如何避免内存泄漏,特别是WeakReference的使用场景,现在应该是在深入理解这个概念。首先,我需要回忆一下强引用弱引用的基本定义,然后想想怎么用简单的中文解释清楚。 强引用应该就是普通的对象引用,只要存在强引用,垃圾回收器就不会回收那个对象。比如用户之前提到的例子,比如事件未注销或者静态集合持有对象,导致对象无法被回收,这就是强引用导致的内存泄漏问题。 弱引用的话,像是WeakReference,允许引用对象,但不会阻止垃圾回收。当内存不足时,即使有弱引用,对象还是会被回收。这时候需要检查弱引用是否还存活,如果被回收了,就需要重新创建或者处理。用户之前提到的缓存系统事件监听都是典型的使用场景。 用户可能现在想更基础的理解这两个概念,而不仅仅是使用场景。可能需要举一些日常生活中的例子,比如强引用像是牢牢抓住一个东西,而弱引用像是用绳子轻轻系着,东西还在的时候可以用,但一旦需要,绳子会自动松开。 另外,需要区分短弱引用弱引用,可能用户没有提到,但作为补充说明可以让回答更全面。同时,可能要注意到WeakReference<T>普通WeakReference的区别,之前回答中也有提到泛型版本更安全。 还要注意用户可能对垃圾回收机制不太了解,需要简单解释一下GC如何根据引用来判断对象是否存活。比如,强引用会增加对象的引用计数,而弱引用不会,这样当只有弱引用存在时,对象就会被回收。 可能需要检查之前的回答是否有遗漏点,比如强引用弱引用的定义对比,使用时的注意事项,比如性能问题,或者如何正确使用弱引用避免空引用异常。 最后,结构上应该先定义强引用,再弱引用,对比两者的区别,应用场景,以及注意事项。确保用户能一步步理解,从基本概念到实际应用,再到注意点,结构清晰。</think>### 强引用弱引用的核心区别 #### 一、强引用(Strong Reference) **定义**: 普通对象引用,只要存在强引用指向对象,垃圾回收器(GC)**永远不会回收该对象**,即使内存不足时也优先触发内存扩容而非回收。 **代码示例**: ```csharp // 强引用示例 var obj = new MyClass(); // obj是强引用 List<MyClass> cache = new List<MyClass> { obj }; // cache仍持有强引用 → obj永远不会被回收 ``` **特点**: - **内存安全性**:对象生命周期完全可控 - **风险**:过度使用会导致内存泄漏(如忘记移除引用) **典型场景**: - 核心业务对象 - 需要长期驻留内存的数据 --- #### 二、弱引用(Weak Reference) **定义**: 特殊引用类型,允许访问对象但**不阻止GC回收**。当内存不足时,GC会回收仅被弱引用指向的对象。 **代码示例**: ```csharp // 弱引用示例 var obj = new MyClass(); WeakReference<MyClass> weakRef = new WeakReference<MyClass>(obj); obj = null; // 移除强引用 GC.Collect(); // 触发垃圾回收 if (weakRef.TryGetTarget(out MyClass target)) { // 对象未被回收时可访问 } else { // 对象已被回收 → 需要重建 } ``` **特点**: - **内存友好性**:自动释放非关键资源 - **不确定性**:对象可能随时被回收,访问前必须检查有效性 --- ### 三、对比表 | 特性 | 强引用 | 弱引用 | |---------------------|--------------------------------|--------------------------------| | **GC回收影响** | 阻止回收 | 不阻止回收 | | **内存泄漏风险** | 高(需手动管理) | 低(自动释放) | | **访问可靠性** | 始终有效 | 需检查有效性 | | **典型用途** | 核心数据、长期持有对象 | 缓存、监听器、辅助数据 | --- ### 四、弱引用高级类型 1. **短弱引用(Short Weak Reference)** ```csharp new WeakReference(obj, trackResurrection: false); ``` - 对象被回收后立即失效(**常用类型**) 2. **长弱引用(Long Weak Reference)** ```csharp new WeakReference(obj, trackResurrection: true); ``` - 允许追踪对象复活(`Finalize`方法执行后仍可访问) --- ### 五、实战注意事项 1. **不要依赖弱引用存储关键数据** ```csharp // 错误用法:可能随时丢失数据 WeakReference<Config> configRef = new WeakReference(LoadConfig()); // 正确用法:关键数据使用强引用+弱引用双保险 Config _configStrongRef; // 强引用保底 WeakReference<Config> _configWeakRef; ``` 2. **高频访问场景需谨慎** ```csharp // 每次访问都检查弱引用 → 性能损耗 if (weakRef.TryGetTarget(out var obj)) { obj.Process(); } // 解决方案:临时转换为强引用 if (weakRef.TryGetTarget(out var tempObj)) { var strongRef = tempObj; // 创建局部强引用 strongRef.Process(); strongRef.AnotherOperation(); } ``` 3. **与ConditionalWeakTable配合** ```csharp // 键值均为弱引用的高级结构 var weakTable = new ConditionalWeakTable<Key, Value>(); weakTable.Add(key, value); // key被回收时自动移除对应条目 ``` --- ### 六、比喻理解 - **强引用** → 用铁链锁住物品:只要铁链存在,物品永远留在房间 - **弱引用** → 用纸条标记物品位置:当房间需要腾空间时,纸条标记的物品会被优先清理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值