ARC中用代码检测一个对象有没有释放掉

你试过在ARC中用代码检测对象有没有释放掉这种事情呢?即使你想过肯定也不知道怎么去实现,因为,这里会用到一个你基本上没怎么接触过的类:NSHashTable.

我们以检测导航控制器push出一个新的控制器为例,以下是效果:

所有你需要的源码:

ObjectDetector.h + ObjectDetector.m

//
// ObjectDetector.h
// ARCBlock
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import <Foundation/Foundation.h> @interface ObjectDetector : NSObject + (void)startWatch;
+ (void)addToWatch:(id)object;
+ (NSArray *)allObjects; @end
//
// ObjectDetector.m
// ARCBlock
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "ObjectDetector.h" #ifndef GCDExecOnce
#define GCDExecOnce(block) \
{ \
static dispatch_once_t predicate = ; \
dispatch_once(&predicate, block); \
}
#endif static NSHashTable *_table = nil;
static dispatch_source_t _dispatchSource = nil;
static dispatch_queue_t _dispatchQueue = nil; @implementation ObjectDetector + (void)initialize
{
if (self == [ObjectDetector class])
{
_table = [NSHashTable weakObjectsHashTable];
_dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
_dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, , , _dispatchQueue); dispatch_source_set_timer(_dispatchSource,
dispatch_time(DISPATCH_TIME_NOW, ),
NSEC_PER_SEC,
); dispatch_source_set_event_handler(_dispatchSource, ^{
NSLog(@"\n[==ObjectDetector LIST==]\n%@", _table);
});
}
} + (void)startWatch
{
GCDExecOnce(^{
dispatch_resume(_dispatchSource);
});
} + (void)addToWatch:(id)object
{
if (object == nil)
{
NSLog(@"object should not be nil.");
return;
} if ([_table containsObject:object] == NO)
{
[_table addObject:object];
}
} + (NSArray *)allObjects
{
return [_table allObjects];
} @end

****-Prefix.pch

//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
// #import <Availability.h> #ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif #ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h> #import "ObjectDetector.h"
#endif

AppDelegate.h

//
// AppDelegate.m
// NSHashTable
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "AppDelegate.h"
#import "RootViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UINavigationController *NC = \
[[UINavigationController alloc] initWithRootViewController:[RootViewController new]]; self.window.rootViewController = NC; // 开始检测
[ObjectDetector startWatch]; self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
} @end

RootViewController.m

//
// RootViewController.m
// NSHashTable
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "RootViewController.h"
#import "SecondViewController.h" @interface RootViewController () @end @implementation RootViewController - (void)viewDidLoad
{
[super viewDidLoad]; self.title = @"任重而道远";
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(, , , )];
button.center = self.view.center;
button.layer.borderWidth = .f;
button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight"
size:.f];
[button setTitle:@"YouXianMing" forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button addTarget:self
action:@selector(buttonEvent:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
} - (void)buttonEvent:(UIButton *)button
{
[self.navigationController pushViewController:[SecondViewController new]
animated:YES];
} @end

SecondViewController.m

//
// SecondViewController.m
// NSHashTable
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "SecondViewController.h" @interface SecondViewController () @end @implementation SecondViewController - (void)viewDidLoad
{
[super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor];
self.title = @"天道酬勤"; // 添加检测对象
[ObjectDetector addToWatch:self];
} @end

核心代码详解:

核心代码包括了用单例创建的GCD定时器以及维护一个弱引用集合

然后开启打印检测:

然后添加被检测对象:

大概就酱紫,是不是很容易呢-_-!,不过我当初想到这个点子可是花了挺长时间的,至于NSHashTable怎么使用,请君自行百度,很容易理解的.

ARC中用代码检测一个对象有没有释放掉的更多相关文章

  1. 基于git diff进行的eslint代码检测

    缘起 在项目中, 通常都会使用代码检测工具来规范团队的代码风格, 比如eslint.随着代码的不断增加, eslint进行代码检测的时间也越来越久.每次检测的时候, 需要检测的文件和实际检测的文件极度 ...

  2. Unity 代码检测单击,双击,拖放

    今天小伙伴问我如何自己写一段代码检测 单击 双击 和 拖放.于是就写了这段代码O(∩_∩)O~ 代码如下: using UnityEngine; using System.Collections; p ...

  3. Jenkins+PMD构建自动化静态代码检测

    前言:软件缺陷是不可避免的,要尽量减少错误并提高软件质量,主要有两在类技术,即缺陷预防和缺陷检测 缺陷预防包括编写更好的设计规范.实施代码审核制度.运行代码静态分析工具.运行单元测试等 PMD是一种开 ...

  4. 2.2、Android Studio通过注解提升代码检测

    使用像Lint这样的代码检测工具可以帮助你发现问题和提升代码,但是代码检测在有些地方很难应用.例如,Android的资源ID,使用一个int类型来表示字符.图像.颜色或者其他资源类型所以代码检测工具不 ...

  5. 搭建基于SornaQube的自动化安全代码检测平台

    一.背景和目的 近年来,随着新业务.新技术的快速发展,应用软件安全缺陷层出不穷.虽然一般情况下,开发者基本都会有单元测试.每日构建.功能测试等环节来保证应用的可用性.但在安全缺陷方面,缺乏安全意识.技 ...

  6. iOS开发之一句代码检测APP版本的更新

    提示更新效果图如下,当然也是可以自定义类似与AlertView相似的自定义view,如京东.网易云音乐都是自定义了这种提示框的view.以下只展示,从App Store获取到app信息.并解析app信 ...

  7. eslint 代码检测工具

    jshint 检测工具不够灵活下,道格拉斯(何许人也?json创造者,javascript重要任务,犀牛那本书就是他写的). 文档地址: 中文地址 English 安装 利用npm全局安装eslint ...

  8. StyleCop(C#代码检测工具)

    StyleCop(C#代码检测工具)   一.StyleCop是微软的一个开源的静态代码分析工具,检查c#代码一致性和编码风格. 二.下载地址   http://stylecop.codeplex.c ...

  9. 如何在Drupal7中用代码批量创建节点、评论和分类

    最近,我忙于一个网站迁移工作.网站是使用某个老式CMS建立的,有一定数量的文章.不同的分类数据和用户评论.我的团队被雇来把这些数据从这个浪费人力物力的老式CMS上完整的迁移到功能更现代的开源Drupa ...

随机推荐

  1. 《大数据日知录》读书笔记-ch15机器学习:范型与架构

    机器学习算法特点:迭代运算 损失函数最小化训练过程中,在巨大参数空间中迭代寻找最优解 比如:主题模型.回归.矩阵分解.SVM.深度学习 分布式机器学习的挑战: - 网络通信效率 - 不同节点执行速度不 ...

  2. 案例19-页面使用ajax显示类别菜单

    1 版本一 版本只能在首页显示类别,当切换到了其它页面就不会显示 1 web层IndexServlet代码 package www.test.web.servlet; import java.io.I ...

  3. 【lua】LWT request请求处理

    request请求处理 通过mod_lwt模块提供的处理程序来调用Lua脚本处理HTTP请求.具体流程: 判断该请求是否由LWT处理,如果不是,拒绝处理请求; 判断Lua脚本文件是否存在,如果不存在, ...

  4. git 学习之基础知识

    在前面的一个帖子中我们知道了不同的版本控制系统的不同,在这个帖子中我们会大致的了解到它们是管理各个版本的,这对我们学习 git 是很有帮助的. 对于集中式的版本控制系统来说每次的更新主要记录内容的具体 ...

  5. GITHUB一个新的项目发布

    经过一段时间的积累,写了一些代码,发现好多功能有好几个系统都在用,但是公司的开发过程中,并没有一个对通用功能提取整合普遍化的一个流程,所以就自己将在项目开发过程中遇到的一些功能提取出来,并尽量做到普适 ...

  6. java多线程开发之CyclicBarrier,CountDownLatch

    最近研究了一个别人的源码,其中用到多个线程并行操作一个文件,并且在所有线程全部结束后才进行主线程后面的处理. 其用到java.util.concurrent.CyclicBarrier 这个类. Cy ...

  7. 8086处理器的无条件转移指令——《x86汇编语言:从实模式到保护模式》读书笔记13

    本博文是对原书8.3.10的内容的总结. 一.相对短转移 指令格式是: jmp short 标号 标号也可以替换成具体的数值(标号和数值是等价的),例如 jmp short 0x2000 说明: (1 ...

  8. jquery清空下拉框,保留第一个

    js中可以document.getElementById("id").options.length = 1;设置 jquery中的设置方法:$("#id option[i ...

  9. Ubuntu apache

    Linux系统为Ubuntu 1. 启动apache服务 # /etc/init.d/apache2 start 2. 重启apache服务 # /etc/init.d/apache2 restart ...

  10. Tomcat热启动

    ===== 2017.7.1 ===== 如果是对原来的类方法修改,那么热启动非常好用:如果是添加了新的类或方法(非最上层的controller),那么此方法也是好用的:但是如果是在controlle ...