首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >目标C:创建后的swizzle对象方法

目标C:创建后的swizzle对象方法
EN

Stack Overflow用户
提问于 2012-03-31 03:27:35
回答 3查看 1.8K关注 0票数 2

我想要在对象创建后对对象方法进行swizzle操作。

示例:

代码语言:javascript
复制
@interface MyObj: NSObject
-(NSString*) foo;
-(NSString*) bar;
@end

@implementation MyObj
-(NSString*) foo {return @"foo";}
-(NSString*) bar {return @"bar";}
@end

void Swizzle(object, SEL source, SEL, dest);

..。

代码语言:javascript
复制
MyObj* obj = [[[MyObj alloc] init] autorelease];

NSLog(@"%@", [obj foo]);
Swizzle(obj, @selector(foo), @selector(bar));
NSLog(@"%@", [obj foo]);

输出:

代码语言:javascript
复制
foo
bar

在创建对象之前,我已经看过很多swizzling的examples。但是,正如您所看到的,我希望在创建对象后进行swizzle。

这是因为我想跟踪将要发布的对象(比如NSThread)。我不想大肆宣扬NSObject dealloc,因为这似乎有点过头了。我宁愿只搅动我试图跟踪的对象。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-08-09 05:25:36

我最终得到的解决方案是使用objc_setAssociatedObject(线程、键、对象、OBJC_ASSOCIATION_RETAIN_NONATOMIC);

这样,我就可以检测到线程何时被释放,并进行所需的清理。

票数 0
EN

Stack Overflow用户

发布于 2012-03-31 03:50:13

老实说,这似乎是避免使用Instruments的不明智尝试。如果是这样的话,正确的答案是“只使用工具”。

但要真正回答这个问题:你不能对单个对象做到这一点。方法-甚至实例方法-是按类定义的,而不是按对象定义的。在每个对象的基础上覆盖方法的唯一方法是动态创建对象类的子类,该子类覆盖您感兴趣的方法,并对对象进行isa,以便它使用子类的查找表。(这基本上就是KVO在幕后进行神奇通知的方式。)再说一次,这有点麻烦,而且通常比它的价值要多得多,所以在你这样做之前,我真的会三思而后行(或三次)考虑这是否真的有必要。对于我能想到的几乎任何用例,都有一种更干净的方法来实现相同的目标,而不涉及运行时巫毒。

票数 3
EN

Stack Overflow用户

发布于 2012-03-31 03:42:41

您不能切换对象,只能切换特定的类。此外,选择器的实现是缓存的,当您切换时,缓存可能不会自动清除,这意味着新方法不会被使用。

我建议在您想要跟踪的类中覆盖(或swizzling) dealloc,并使用属性来确定是否应该执行跟踪代码。

代码语言:javascript
复制
@property (nonatomic) BOOL shouldTrackDealloc;

@synthesize shouldTrackDealloc;
- (void)dealloc {
    if(self.shouldTrackDealloc) {
        NSLog(@"dealloc of %@",self);
    }
    ...
}

如果您正在跟踪框架类,您将无法使用@synthesize,因为实例变量将不在正确的类中,但是您可以使用associated references

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9949288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档