2012-03-30 15 views
2

オブジェクトを作成した後、オブジェクトメソッドをスウィズルしたいと思います。目的C:作成後スウィズルオブジェクトメソッド

例:

@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

[オブジェクトがスレッドセーフを受け取るすべてのメッセージを作成するにはどうすればよいですか?](http://stackoverflow.com/questions/8763028/how-can-i-make-every-message-an-object-スレッドセーフです)。私はそれがあるようには見えないが、答えを見て、それが必要であれば、それは容易に広がることを知っている。 –

+0

"Instrumentsを使用するだけです。" – bbum

答えて

0

私が解決した解決策は、objc_setAssociatedObject(スレッド、キー、オブジェクト、OBJC_ASSOCIATION_RETAIN_NONATOMIC)を使用することでした。

このようにして、スレッドが解放されたことを検出して、必要なクリーンアップを行うことができました。

+0

これは@ughoavgfhwが以下で提案したものではありませんか? – sergio

0

オブジェクトをスウィズルすることはできません。特定のクラスのみをスウィズルすることはできません。また、セレクタの実装がキャッシュされていて、そのキャッシュが自動的にクリアされない可能性があります。これは、新しいメソッドが使用されないことを意味します。

トラッキングするクラスに、deallocをオーバーライド(またはスウィズル)し、プロパティを使用してトラッキングコードを実行する必要があるかどうかを判断することをお勧めします。

@property (nonatomic) BOOL shouldTrackDealloc; 

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

あなたはフレームワーククラスを追跡している場合は、インスタンス変数は、右のクラスではありませんので、あなたは、@synthesizeを使用することはできませんが、代わりにassociated referencesを使用することができます。

2

これは、正直なところ、インストゥルメントの使用を避けるための不適切な試みのようです。その場合、正解は「楽器を使用する」です。

実際に質問に答えるには、個々のオブジェクトでこれを行うことはできません。メソッド(インスタンスメソッドさえも)は、オブジェクトごとではなく、クラスごとに定義されます。オブジェクト単位でメソッドをオーバーライドする唯一の方法は、対象のメソッドをオーバーライドするオブジェクトクラスのサブクラスを動的に作成し、サブクラスのルックアップテーブルを使用するようにオブジェクトをスワイプすることです。 (これは基本的にKVOがどのように魔法の通知をしているかです)また、これはちょっとしたハックであり、一般的にはそれほど難しい問題ですので、これを行う前に、 )これが本当に必要かどうかについて。私が思いつくほとんどのユースケースについては、ランタイムブードゥーを含まない同じ目標を達成するためのよりクリーンな方法があります。

+0

私はInstrumentsを使用しようとしていません。私はクリーンアップを実行できるように、特定のオブジェクトの破壊を追跡したい。サブクラス化に依存しないようにしようとしているので、オブジェクトクラスをサブクラス化したくありません。例:NSThreadが作成され、アクセスするスレッドの新しいオブジェクトを提供したいとします。スレッドが死んだら、このオブジェクトを削除します。このクラスのユーザーは、スレッドオブジェクトを削除する必要があることをオブジェクトが認識しているため、スレッドオブジェクトを操作する必要はありません。 – Peter

+0

@PeterGulyas:この場合、このリソースの作成と破棄を処理するNSThreadサブクラスが必要なように思えます。 – Chuck

+0

私は、(deallocだけでなく)あらゆるオブジェクトのメソッドの実行を追跡する機能が必要です。 layoutSubviewsとそれがサブクラス化することなく呼び出されるときを知ってうれしいです。はいサブクラス化は単純な解決策ですが、私は何か厄介なものが欲しいです! – Peter