zoukankan      html  css  js  c++  java
  • ARC中用代码检测一个对象有没有释放掉

    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 = 0; 
    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, 0, 0, _dispatchQueue);
            
            dispatch_source_set_timer(_dispatchSource,
                                      dispatch_time(DISPATCH_TIME_NOW, 0),
                                      NSEC_PER_SEC,
                                      0);
            
            dispatch_source_set_event_handler(_dispatchSource, ^{
                NSLog(@"
    [==ObjectDetector LIST==]
    %@", _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(0, 0, 120, 30)];
        button.center            = self.view.center;
        button.layer.borderWidth = 1.f;
        button.titleLabel.font   = [UIFont fontWithName:@"HelveticaNeue-UltraLight"
                                                   size:20.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怎么使用,请君自行百度,很容易理解的.

  • 相关阅读:
    【转】win8.1下安装ubuntu
    Codeforces 1025G Company Acquisitions (概率期望)
    Codeforces 997D Cycles in Product (点分治、DP计数)
    Codeforces 997E Good Subsegments (线段树)
    Codeforces 1188E Problem from Red Panda (计数)
    Codeforces 1284E New Year and Castle Building (计算几何)
    Codeforces 1322D Reality Show (DP)
    AtCoder AGC043C Giant Graph (图论、SG函数、FWT)
    Codeforces 1305F Kuroni and the Punishment (随机化)
    AtCoder AGC022E Median Replace (字符串、自动机、贪心、计数)
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3864741.html
Copyright © 2011-2022 走看看