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

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

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

所有你需要的源码:

ObjectDetector.h + ObjectDetector.m

  1. //
  2. // ObjectDetector.h
  3. // ARCBlock
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import <Foundation/Foundation.h>
  9.  
  10. @interface ObjectDetector : NSObject
  11.  
  12. + (void)startWatch;
  13. + (void)addToWatch:(id)object;
  14. + (NSArray *)allObjects;
  15.  
  16. @end
  1. //
  2. // ObjectDetector.m
  3. // ARCBlock
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "ObjectDetector.h"
  9.  
  10. #ifndef GCDExecOnce
  11. #define GCDExecOnce(block) \
  12. { \
  13. static dispatch_once_t predicate = ; \
  14. dispatch_once(&predicate, block); \
  15. }
  16. #endif
  17.  
  18. static NSHashTable *_table = nil;
  19. static dispatch_source_t _dispatchSource = nil;
  20. static dispatch_queue_t _dispatchQueue = nil;
  21.  
  22. @implementation ObjectDetector
  23.  
  24. + (void)initialize
  25. {
  26. if (self == [ObjectDetector class])
  27. {
  28. _table = [NSHashTable weakObjectsHashTable];
  29. _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
  30. _dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, , , _dispatchQueue);
  31.  
  32. dispatch_source_set_timer(_dispatchSource,
  33. dispatch_time(DISPATCH_TIME_NOW, ),
  34. NSEC_PER_SEC,
  35. );
  36.  
  37. dispatch_source_set_event_handler(_dispatchSource, ^{
  38. NSLog(@"\n[==ObjectDetector LIST==]\n%@", _table);
  39. });
  40. }
  41. }
  42.  
  43. + (void)startWatch
  44. {
  45. GCDExecOnce(^{
  46. dispatch_resume(_dispatchSource);
  47. });
  48. }
  49.  
  50. + (void)addToWatch:(id)object
  51. {
  52. if (object == nil)
  53. {
  54. NSLog(@"object should not be nil.");
  55. return;
  56. }
  57.  
  58. if ([_table containsObject:object] == NO)
  59. {
  60. [_table addObject:object];
  61. }
  62. }
  63.  
  64. + (NSArray *)allObjects
  65. {
  66. return [_table allObjects];
  67. }
  68.  
  69. @end

****-Prefix.pch

  1. //
  2. // Prefix header
  3. //
  4. // The contents of this file are implicitly included at the beginning of every source file.
  5. //
  6.  
  7. #import <Availability.h>
  8.  
  9. #ifndef __IPHONE_3_0
  10. #warning "This project uses features only available in iOS SDK 3.0 and later."
  11. #endif
  12.  
  13. #ifdef __OBJC__
  14. #import <UIKit/UIKit.h>
  15. #import <Foundation/Foundation.h>
  16.  
  17. #import "ObjectDetector.h"
  18. #endif

AppDelegate.h

  1. //
  2. // AppDelegate.m
  3. // NSHashTable
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "AppDelegate.h"
  9. #import "RootViewController.h"
  10.  
  11. @implementation AppDelegate
  12.  
  13. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  14. {
  15. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  16. // Override point for customization after application launch.
  17. UINavigationController *NC = \
  18. [[UINavigationController alloc] initWithRootViewController:[RootViewController new]];
  19.  
  20. self.window.rootViewController = NC;
  21.  
  22. // 开始检测
  23. [ObjectDetector startWatch];
  24.  
  25. self.window.backgroundColor = [UIColor whiteColor];
  26. [self.window makeKeyAndVisible];
  27. return YES;
  28. }
  29.  
  30. @end

RootViewController.m

  1. //
  2. // RootViewController.m
  3. // NSHashTable
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "RootViewController.h"
  9. #import "SecondViewController.h"
  10.  
  11. @interface RootViewController ()
  12.  
  13. @end
  14.  
  15. @implementation RootViewController
  16.  
  17. - (void)viewDidLoad
  18. {
  19. [super viewDidLoad];
  20.  
  21. self.title = @"任重而道远";
  22. UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(, , , )];
  23. button.center = self.view.center;
  24. button.layer.borderWidth = .f;
  25. button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight"
  26. size:.f];
  27. [button setTitle:@"YouXianMing" forState:UIControlStateNormal];
  28. [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  29. [button addTarget:self
  30. action:@selector(buttonEvent:)
  31. forControlEvents:UIControlEventTouchUpInside];
  32. [self.view addSubview:button];
  33. }
  34.  
  35. - (void)buttonEvent:(UIButton *)button
  36. {
  37. [self.navigationController pushViewController:[SecondViewController new]
  38. animated:YES];
  39. }
  40.  
  41. @end

SecondViewController.m

  1. //
  2. // SecondViewController.m
  3. // NSHashTable
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "SecondViewController.h"
  9.  
  10. @interface SecondViewController ()
  11.  
  12. @end
  13.  
  14. @implementation SecondViewController
  15.  
  16. - (void)viewDidLoad
  17. {
  18. [super viewDidLoad];
  19.  
  20. self.view.backgroundColor = [UIColor whiteColor];
  21. self.title = @"天道酬勤";
  22.  
  23. // 添加检测对象
  24. [ObjectDetector addToWatch:self];
  25. }
  26.  
  27. @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. Ubuntu中搭建git

    1.配置用户名和邮箱 git config --global user.name "xiaoming" git config --global user.email "x ...

  2. 小y的质数

    题目链接:https://ac.nowcoder.com/acm/contest/634/C 链接:https://ac.nowcoder.com/acm/contest/634/C来源:牛客网 题目 ...

  3. 使用java配置来构建spring项目

    java配置是Spring4.x推荐的配置方式,可以完全代替xml配置,java配置是通过@Configuration和@Bean来实现的.@Configuration声明当前类是一个配置类,相当于S ...

  4. selenium+junit4实现参数化自动化测试

    业务场景:在www.1905.com电影网中实现两个用户的登陆操作. 代码如下: package com.m1905.junit; import java.util.Arrays; import ja ...

  5. 遇到Caused by: java.lang.NoClassDefFoundError: javax/validation/ParameterNameProvider

    今天在做spring和hibernate整合的时候遇到这个问题 网上搜找到这里有解决办法 http://blog.csdn.net/jueshengtianya/article/details/122 ...

  6. EntityFrameWork Code First 多对多关系处理

    场景2: 一个文章类别(Category)下含有多篇文章(Article),而文章也可能对应多个类别 Article和Category的代码更改如下: /// <summary> /// ...

  7. 日调度万亿次,微服务框架TSF大规模应用——云+未来峰会开发者专场回顾

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 演讲者:张浩 腾讯云中间件产品负责人 背景:众多开发者中,一定经历类似的甜蜜烦恼,就是当线上业务规模越来越大,系统分支发展越来越多的时候,初 ...

  8. [android] android通信协议

    1.数据区分 手机端:常量存储 服务器端:数据库建表存储 2.数据来源 android,ios,pc,wap 3.数据采集,数据挖掘 IMEI:设备编号 IMSI:SIM卡编号 4.数据加密 4.1R ...

  9. Mysql 删除数据表重复行

    准备示例数据 以下sql创建表,并将示例数据插入到用于演示的contacts表中. CREATE TABLE contacts ( id INT PRIMARY KEY AUTO_INCREMENT, ...

  10. hdu 1565 方格取数(1) 状态压缩dp

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...