我想在创建对象后调用对象方法。
示例:
@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);
...
MyObj* obj = [[[MyObj alloc] init] autorelease];
NSLog(@"%@", [obj foo]);
Swizzle(obj, @selector(foo), @selector(bar));
NSLog(@"%@", [obj foo]);
输出:
foo
bar
在创建对象之前,我已经查看了很多examples的混合。但是,正如您所看到的,我想在创建对象后进行调整。
这是因为我想跟踪要发布的对象(比如NSThread)。我不想调动NSObject dealloc,因为这看起来有点过分。我宁愿只调动我想跟踪的物体。
答案 0 :(得分:3)
这显然是一种不明智的尝试,以避免使用仪器。如果是这样,正确答案是“只使用仪器。”
但要真正回答这个问题:你不能用单个对象做到这一点。方法 - 甚至实例方法 - 是按类定义的,而不是按对象定义的。在每个对象的基础上覆盖方法的唯一方法是动态创建对象类的子类,该子类覆盖您感兴趣的方法,并且isa-swizzle对象,因此它使用子类的查找表。 (这基本上就是KVO在引擎盖下发出魔法通知的方式。)同样,这是一个黑客攻击,通常比它的价值更麻烦,所以在你这样做之前,我真的会三思而后行(或三次) )这是否真的有必要。对于我能想到的几乎任何用例,有一种更简洁的方法来实现不涉及运行时巫术的相同目标。
答案 1 :(得分:1)
你不能混淆一个对象,只能一个特定的类。此外,缓存了选择器的实现,并且当您调用时可能不会自动清除该缓存,这意味着不使用新方法。
我建议在您要跟踪的班级中覆盖(或调整)dealloc
,并使用属性来确定是否应该执行跟踪代码。
@property (nonatomic) BOOL shouldTrackDealloc;
@synthesize shouldTrackDealloc;
- (void)dealloc {
if(self.shouldTrackDealloc) {
NSLog(@"dealloc of %@",self);
}
...
}
如果您正在跟踪框架类,则无法使用@synthesize
,因为实例变量不在正确的类中,但您可以改为使用associated references。
答案 2 :(得分:0)
我最终得到的解决方案是使用objc_setAssociatedObject(线程,密钥,对象,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
这样我可以检测线程何时被释放并进行我需要的清理。