在取消分配任何对象时运行代码

我正在阅读杰夫凯利的这篇文章,并试图做同样的事情。 然而,代码是在ARC被采纳之前编写的,现在无法编译。

http://blog.slaunchaman.com/2011/04/11/fun-with-the-objective-c-runtime-run-code-at-deallocation-of-any-object/

主要问题是在打印输出的这一部分,一些铸造错误,然后阻止释放信息。 我发现它是一个非常有趣的例子,但我似乎无法得到它的工作。

问题是:

0.自动合成属性'block'将 @implementation JKBlockExecutor 使用合成的实例变量'_block',而不是现有的实例变量'block'

1.将块指针类型'voidBlock'(aka'void(^)(void)')转换为C指针类型'const void *'需要桥接转换 Cast of C指针类型'void *'来阻止指针类型' typeof运算(ABLOCK)”(又名'空隙(^ __强)(无效)')需要块= Block_copy(ABLOCK)的桥连铸”; 线

2.块指针类型'voidBlock'(aka'void(^)(void)')转换为C指针类型'const void *'需要 Block_release(block) 进行桥接转换。

typedef void (^voidBlock)(void);

@interface JKBlockExecutor : NSObject {
    voidBlock   block;
}

@property (nonatomic, readwrite, copy) voidBlock    block;

- (id)initWithBlock:(voidBlock)block;

@end

@implementation JKBlockExecutor

@synthesize block;

- (id)initWithBlock:(voidBlock)aBlock
{
    self = [super init];

    if (self) {
        block = Block_copy(aBlock);
    }

    return self;
}

- (void)dealloc
{
    if (block != nil) {
        block();
        Block_release(block);
    }

    [super dealloc];
}

@end

这是他在NSObject上创建一个类别的地方。

const void *runAtDeallocBlockKey = &runAtDeallocBlockKey;

@interface NSObject (JK_RunAtDealloc)

- (void)runAtDealloc:(voidBlock)block;

@end

@implementation NSObject (JK_RunAtDealloc)

- (void)runAtDealloc:(voidBlock)block
{
    if (block) {
        JKBlockExecutor *executor = [[JKBlockExecutor alloc] initWithBlock:block];

        objc_setAssociatedObject(self,
                                 runAtDeallocBlockKey,
                                 executor,
                                 OBJC_ASSOCIATION_RETAIN);

        [executor release];
    }
}

@end

这就是你如何执行这个例子。

NSObject *foo = [[NSObject alloc] init];

[foo runAtDealloc:^{
    NSLog(@"Deallocating foo!");
}];

[foo release];

或另一种获取其他信息的方式。

NSObject *foo = [[NSObject alloc] init];

__block id objectRef = foo;

[foo runAtDealloc:^{
    NSLog(@"Deallocating foo at address %p!", objectRef);
}];

[foo release];

该代码可以以某种方式修复吗? 我拿出所有的发布消息都无济于事。


下面的代码构建和工作(或至少看起来如此),并打印出“释放foo!”。 当我期望它打印它。 第1部分:

typedef void (^voidBlock)(void);

@interface JKBlockExecutor : NSObject {
    voidBlock   block;
}

@property (nonatomic, readwrite, copy) voidBlock    block;

- (id)initWithBlock:(voidBlock)block;

@end

@implementation JKBlockExecutor

@synthesize block = block;

- (id)initWithBlock:(voidBlock)aBlock
{
    self = [super init];

    if (self) {
        block = [aBlock copy];
    }

    return self;
}

- (void)dealloc
{
    if (block != nil) {
        block();
        block = nil;
    }
}

@end

第2部分:

const void *runAtDeallocBlockKey = &runAtDeallocBlockKey;

@interface NSObject (JK_RunAtDealloc)

- (void)runAtDealloc:(voidBlock)block;

@end

@implementation NSObject (JK_RunAtDealloc)

- (void)runAtDealloc:(voidBlock)block
{
    if (block) {
        JKBlockExecutor *executor = [[JKBlockExecutor alloc] initWithBlock:block];

        objc_setAssociatedObject(self,
                                 runAtDeallocBlockKey,
                                 executor,
                                 OBJC_ASSOCIATION_RETAIN);
    }
}

@end

测试它是否有效:

@autoreleasepool {
        NSObject *foo = [[NSObject alloc] init];

        [foo runAtDealloc:^{
            NSLog(@"Deallocating foo!");
        }];
    }

编辑

改变了Block_release(block); block = nil;


如果您想了解更多关于下面的代码的知识,请访问Objective-C运行库:运行代码解除任何对象的释放

第1部分:创建一个类:我们想要释放的对象何时发生---这个类就像一个事件:当目标obj dealloc发生时,使用阻止来执行事件。

// .m file
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
// the object We Want To Be Released When That Happens--- this class is like an event:when the target obj dealloc,it happens。use block to execute the event 。


typedef void (^voidBlock)(void);

@interface CYLBlockExecutor : NSObject 

- (id)initWithBlock:(voidBlock)block;

@end


// .m file
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
// the object We Want To Be Released When That Happens--- this class is like an event:when the target obj dealloc,it happens。use block to execute the event 。

#import "CYLBlockExecutor.h"

@interface CYLBlockExecutor() {
    voidBlock _block;
}
@implementation CYLBlockExecutor

- (id)initWithBlock:(voidBlock)aBlock
{
    self = [super init];

    if (self) {
        _block = [aBlock copy];
    }

    return self;
}

- (void)dealloc
{
    _block ? _block() : nil;
}

@end

第2部分:核心代码:使用运行时来实现cyl_runAtDealloc方法

// CYLNSObject+RunAtDealloc.h file
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
// use runtime to realize cyl_runAtDealloc method

#import "CYLBlockExecutor.h"

const void *runAtDeallocBlockKey = &runAtDeallocBlockKey;

@interface NSObject (CYLRunAtDealloc)

- (void)cyl_runAtDealloc:(voidBlock)block;

@end


// CYLNSObject+RunAtDealloc.m file
// http://weibo.com/luohanchenyilong/
// https://github.com/ChenYilong
// use runtime to realize cyl_runAtDealloc method

#import "CYLNSObject+RunAtDealloc.h"
#import "CYLBlockExecutor.h"

@implementation NSObject (CYLRunAtDealloc)

- (void)cyl_runAtDealloc:(voidBlock)block
{
    if (block) {
        CYLBlockExecutor *executor = [[CYLBlockExecutor alloc] initWithBlock:block];

        objc_setAssociatedObject(self,
                                 runAtDeallocBlockKey,
                                 executor,
                                 OBJC_ASSOCIATION_RETAIN);
    }
}

@end

如何使用 :

#import "CYLNSObject+RunAtDealloc.h"

然后

    NSObject *foo = [[NSObject alloc] init];

    [foo cyl_runAtDealloc:^{
        NSLog(@"Deallocating foo!");
    }];
链接地址: http://www.djcxy.com/p/44915.html

上一篇: Run Code at Deallocation of Any Object

下一篇: Convert const T* const to T*