问题

weak 变量在引用计数为0时,会被自动设置成 nil,这个特性是如何实现的?

答案

在 Friday QA 上,有一期专门介绍 weak 的实现原理。https://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html

《Objective-C高级编程》一书中也介绍了相关的内容。

简单来说,系统有一个全局的 CFMutableDictionary 实例,来保存每个对象的 weak 指针列表,因为每个对象可能有多个 weak 指针,所以这个实例的值是 CFMutableSet 类型。

剩下我们要做的,就是在引用计数变成 0 的时候,去这个全局的字典里面,找到所有的 weak 指针,将其值设置成 nil。如何做到这一点呢?Friday QA 上介绍了一种类似 KVO 实现的方式。当对象存在 weak 指针时,我们可以将这个实例指向一个新创建的子类,然后修改这个子类的 release 方法,在 release 方法中,去从全局的 CFMutableDictionary 字典中找到所有的 weak 对象,并且设置成 nil。我摘抄了 Friday QA 上的实现的核心代码,如下:

Class subclass = objc_allocateClassPair(class, newNameC, 0);
Method release = class_getInstanceMethod(class, @selector(release));
Method dealloc = class_getInstanceMethod(class, @selector(dealloc));
class_addMethod(subclass, @selector(release), (IMP)CustomSubclassRelease, method_getTypeEncoding(release));
class_addMethod(subclass, @selector(dealloc), (IMP)CustomSubclassDealloc, method_getTypeEncoding(dealloc));
objc_registerClassPair(subclass);

当然,这并不代表苹果官方是这么实现的,因为苹果的这部分代码并没有开源。《Objective-C高级编程》一书中介绍了 GNUStep 项目中的开源代码,思想也是类似的。所以我认为虽然实现细节会有差异,但是大致的实现思路应该差别不大。

weak 的内部实现原理的更多相关文章

  1. iOS 面试题(五):weak 的内部实现原理 --转自唐巧

    问题 weak 变量在引用计数为0时,会被自动设置成 nil,这个特性是如何实现的? 答案 在 Friday QA 上,有一期专门介绍 weak 的实现原理.https://mikeash.com/p ...

  2. Mininet的内部实现原理简介

    原文发表在我的博客主页,转载请注明出处. 前言 之前模拟仿真网络一直用的是Mininet,包括写了一些关于Mininet安装,和真实网络相连接,Mininet简历拓扑的博客,但是大多数都是局限于具体步 ...

  3. KVO内部实现原理

    KVO的原理: 只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象, (格式如:NSKVONotifying_className), 并且重写自动生成的子类对象的被监听 ...

  4. Angular单页应用&AngularJS内部实现原理

    回顾 自定义指令 登录后获取登录信息session 首先在登录验证的时候保存一个user 在学生管理页面中运用ajax调用获取到登录的用户信息 对注销按钮添加点击事件:调用ajax在表现层给user赋 ...

  5. 8. 理解ZooKeeper的内部工作原理

    到目前为止,我们已经讨论了ZooKeeper服务的基础知识,并详细了解了数据模型及其属性. 我们也熟悉了ZooKeeper 监视(watch)的概念,监视就是在ZooKeeper命名空间中的znode ...

  6. Redis有序集内部实现原理分析(二)

    Redis技术交流群481804090 Redis:https://github.com/zwjlpeng/Redis_Deep_Read 本篇博文紧随上篇Redis有序集内部实现原理分析,在这篇博文 ...

  7. Apache Lucene评分机制的内部工作原理

    Apache Lucene评分机制的内部工作原理' 第5章

  8. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  9. 4000余字为你讲透Codis内部工作原理

    一.引言 Codis是一个分布式 Redis 解决方案,可以管理数量巨大的Redis节点.个推作为专业的第三方推送服务商,多年来专注于为开发者提供高效稳定的消息推送服务.每天通过个推平台下发的消息数量 ...

随机推荐

  1. java Map根据value排序

    通用方法 public class MapUtil { public static <K, V extends Comparable<? super V>> Map<K, ...

  2. 基于Django进行简单的微信开发

    代码地址如下:http://www.demodashi.com/demo/11756.html 一.微信公众号的准备: 1. 注册 访问地址:https://mp.weixin.qq.com/ 按照提 ...

  3. 改变UITextField的Placeholder颜色

    通过 attributedPlaceholder 属性来改变 if([textField respondsToSelector:@selector(setAttributedPlaceholder:) ...

  4. BAT都来参加的 DevOps Master 培训

    原文:http://www.sohu.com/a/128425731_262549 自高效运维社区开设 DevOps Master 认证培训以来,已经总共有120多人拿到证书,其中在今年春节后,有68 ...

  5. C#中String.Empty、NULL与""三者的区别

    String.Empty和""是一样的,都是空,习惯用string.empty. Null和他们就有区别了,就是没有值,也没分配地址,此处可以理解成什么都没有.

  6. redis 的安装与启动

    1.redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis 是一个高性能的key-val ...

  7. 【.net项目中。。】.net一般处理程序使用方法

    1.基本原理图 IsReusable属性用来表示在IHttpHandlerFactory对象创建IHttpHandler的时候是否能够将这个Handler存入池中以便重用. 一般处理程序(HttpHa ...

  8. maven初始搭建一个基础项目(spring mvc+spring+jdbc mysql+jstl)

    技术选型: 一.项目搭建: 1)创建maven项目 (我博客里面有介绍) 选择aptach的maven-archetype-webapp 填入groupIDhe artifactId等 确认项目名称 ...

  9. 【Hadoop基础教程】4、Hadoop之完全分布式环境搭建

    上一篇blog我们完成了Hadoop伪分布式环境的搭建,伪分布式模式也叫单节点集群模式, NameNode.SecondaryNameNode.DataNode.JobTracker.TaskTrac ...

  10. 写sql语句统计各个学生各科成绩(case when用法)

    尊重原创:http://blog.csdn.net/love_java_cc/article/details/78268326 有如下一张表score: 建表语句: CREATE TABLE `sco ...