__weak如何实现对象值自动设置为nil

__weak如何实现对象值自动设置为nil的

在开始讲解__weak机制之前,先来一些铺垫

ARC 的实现

苹果的官方说明中称,ARC是“由编译器进行内存管理”的,但实际上只有编译器是无法完全胜任的,ARC还依赖OC运行时库,也就是说ARC是通过以下工具、库来实现的:

● clang (LLVM 编译器)3.0以上

● objc4 OC运行时库 493.9以上

如果按照苹果的说明,仅仅是编译器管理内存的,那么__weak修饰符也可以在iOS 4中使用

__weak 修饰符

就像我们知道的那样__weak修饰符提供了如同魔法般的公能。

● 若使用__weak修饰符的变量引用对象被废弃时,则将nil赋值给该变量

● 使用附有__weak修饰符的变量,就是使用注册到autoreleasepool的对象。

我们来看看它的实现:

{id __weak obj_weak = obj;//obj已被赋值,并且是strong类型的}
/*编译器的模拟代码*/id obj_weak;objc_initWeak(&obj_weak,obj);//初始化附有__weak修饰符的变量objc_destroyWeak(&obj_weak);//释放该变量

其中objc_initWeak objc_destroyWeak都是调用了objc_storeWeak函数,所以,上面的代码可以转化为下面的代码

id obj_weak;obj_weak = 0;objc_storeWeak(&obj_weak,obj);objc_storeWeak(&obj,0);objc_storeWeak函数以把obj的地址作为键值,obj_weak的地址作为值存放到weak表(weak是一个hash表)中。

释放对象时,废弃对象的同时,程序的动作是怎样的呢?对象通过objc_release释放。

1. objc_release

2. 因为引用计数为0所以执行dealloc

3. _objc_rootDealloc

4. object_dispose

5. objc_destructInstance

6. objc_clear_deallocating

而,调用objc_clear_deallocating的动作如下:

1. 从weak表中获取废弃对象的地址为键值的记录。

2. 将包含在记录中的所有附有__weak修饰符变量的地址,赋值为nil

3. 从weak表中删除记录

4. 从引用计数表中删除废弃对象的地址作为键值的记录

根据以上步骤,前面说的如果附有__weak修饰符的变量所引用的对象被废弃,则将nil赋值给这个变量,这个功能即被实现。

__weak的第二个功能,使用__weak 修饰符的变量,即是使用注册到autoreleasepool中的对象。

{id __weak obj_weak = obj;//obj已被赋值,并且是strong类型的NSLog(@"%@",obj_weak);}

该代码转化为如下形式:

/*编译器的模拟代码*/id obj_weak;objc_initweak(&obj_weak,obj);id tmp = objc_loadWeakRetained(&obj_weak);objc_autorelease(tmp);NSLog(@"%@",tmp);objc_destroyWeak(&obj_weak);

与被赋值时相比,在使用附有__weak修饰符变量的情形下,增加了对objc_loadWeakRetained函数和objc_autorelease函数的调用。这些函数的动作如下:

1. objc_loadWeakRetained函数取出附有__weak修饰符变量所引用的对象并retain

2. objc_autorelease函数将对象注册到autorelease中。

由此可知,因为附有__weak修饰符变量所引用的对象这样被注册到autorelease中,所以在@autoreleasepool块结束之前都可以放心使用。

注:OC中有一些类,并不支持ARC,例如NSMachPort类。可以通过allowsWeakReference/retainWeakReference方法来判断是否支持ARC

编译器 苹果 如何 先来

时间: 2024-10-30 05:41:27

__weak如何实现对象值自动设置为nil的相关文章

__weak如何实现对象值自动设置为nil的

在开始讲解__weak机制之前,先来一些铺垫 ARC 的实现 苹果的官方说明中称,ARC是"由编译器进行内存管理"的,但实际上只有编译器是无法完全胜任的,ARC还依赖OC运行时库,也就是说ARC是通过以下工具.库来实现的: ● clang (LLVM 编译器)3.0以上 ● objc4 OC运行时库 493.9以上 如果按照苹果的说明,仅仅是编译器管理内存的,那么__weak修饰符也可以在iOS 4中使用 __weak 修饰符 就像我们知道的那样__weak修饰符提供了如同魔法般的公能

利用反射机制,对对象的属性值进行自动设置

import java.lang.reflect.Method; /** * 对象的属性值自动设置,利用反射机制 */ public class AutoSet { /** * 将源对象的属性值赋值到目标对象,属性名一致,且源对象有get方法,目标对象有set方法 * @param src 源对象 * @param target 目标对象 * @return 赋值后的目标对象 */ public static Object autoGetterAndSetter(Object src, Obje

DOM元素属性值如果设置为对象

结论:内部会调用toString方法,将设置的对象转换为字符串添加给相应的属性: 这个问题呢,是通过jQuery的each方法中,回调函数的this指向问题而来: 我们知道,回调函数中的this如果指向的是基本数据类型,那么系统会自动将这个基本数据类型的值包装为对应的对象类型: 就比如: 数组里面存的是string类型的值,然后jq实例调用each方法,打印的this如下图所示: this指向的基本数据类型的值被转换为了String类型: 但是这里说的不是这个问题,而是和这个问题类似,我们在给D

MySQL 设置表的属性值自动增加

属性值自动增加,比如 id 这一列,每新增一条记录,id 字段值自动加 1. 注意:设置自动增加的字段必须为主键的一部分 语法:字段名  数据类型  AUTO_INCREMENT

设置表的属性值自动增加

设置表的属性值自动增加,比如插入第一条记录时 id 为 1,插入第二条记录时 id 为 2,以此类推,没增加一条记录,字段值自动加 1 mysql> CREATE TABLE tb_emp8    -> (    -> id INT(11) PRIMARY KEY AUTO_INCREMENT,   # 指定员工的编号自动递增    -> name VARCHAR(25) NOT NULL,    -> deptId INT(11),    -> salary FLOA

反射原理读取对象属性并设置属性值

Dictionary<string, string> dicNodes = new Dictionary<string, string>(); foreach (XmlNode node in nodes.ChildNodes) { if (node.NodeType==XmlNodeType.Element) { dicNodes.Add(node.Attributes["name"].Value,node.Attributes["value&quo

unreal3对象属性自动从配置文件中加载的机制

unrealscript中有两个与属性自动配置相关的关键字: config/globalconfig 当把它们应用于属性时,对象在创建后,该属性的初始值会被自动设置为相对应ini文件中的值. 举例来说,如有一个类: class HNet extends Object config(game) native(net); //var globalconfig string host;var config string host; function test() { `Log("HNet test,

(转载)你好,C++(11)如何用string数据类型表示一串文字?根据初始值自动推断数据类型的auto关键字(C++ 11)

你好,C++(11)如何用string数据类型表示一串文字?根据初始值自动推断数据类型的auto关键字(C++ 11) 3.5.2  字符串类型 使用char类型的变量我们可以表示单个字符,那么,我们又该如何表示拥有多个字符的字符串呢? 我们注意到,一个字符串是由多个字符串连起来形成的.很自然地,一种最简单直接的方法就是利用数组(一种数据组织管理方式,它将多个相同类型的数据元素组织起来,形成一个数据序列以便于访问.更多可以参考后文3.6小节对数组的介绍)来保存一个字符串中的各个字符,最后用一个特

你好,C++(11)如何用string数据类型表示一串文字?根据初始值自动推断数据类型的auto关键字(C++ 11)

3.5.2  字符串类型 使用char类型的变量我们可以表示单个字符,那么,我们又该如何表示拥有多个字符的字符串呢? 我们注意到,一个字符串是由多个字符串连起来形成的.很自然地,一种最简单直接的方法就是利用数组(一种数据组织管理方式,它将多个相同类型的数据元素组织起来,形成一个数据序列以便于访问.更多可以参考后文3.6小节对数组的介绍)来保存一个字符串中的各个字符,最后用一个特殊字符'\0'表示字符串的结束,以此来将多个char类型的字符数据串联成字符串.例如: // 定义一个字符数组,用以保存