メソッドのスウィズリングを利用したいのですが、簡単な例でさえうまくいきません。概念が何であるかを誤解している可能性がありますが、私が知る限り、メソッドの実装を入れ替えることができます。
A と B の 2 つのメソッドが与えられた場合、A を呼び出すと代わりに B が実行されるように、それらの実装を入れ替えたいと思います。スウィズリングの例をいくつか見つけました ( example1およびexample2 )。これをテストするクラスを含む新しいプロジェクトを作成しました。
class Swizzle: NSObject
{
func method()
{
print("A");
}
}
extension Swizzle
{
override class func initialize()
{
struct Static
{
static var token: dispatch_once_t = 0;
}
// make sure this isn't a subclass
if (self !== Swizzle.self)
{
return;
}
dispatch_once(&Static.token)
{
let originalSelector = Selector("method");
let swizzledSelector = Selector("methodExt");
let originalMethod = class_getInstanceMethod(self, originalSelector);
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
print(method_getImplementation(originalMethod));
print(method_getImplementation(swizzledMethod));
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if didAddMethod
{
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
else
{
method_exchangeImplementations(originalMethod, swizzledMethod);
}
print(method_getImplementation(originalMethod));
print(method_getImplementation(swizzledMethod));
}
}
func methodExt()
{
print("B");
}
}
次に、それを実行しようとします
var s = Swizzle();
s.method();
予想される出力は「B」ですが、「A」はまだ印刷中です。私のコードからわかるようIMP
に、スウィズル操作の前後にそれぞれのプリントを含めました。これらのプリントは、交換が行われていることを示していますが、出力は同じままです。
出力:
0x000000010251a920
0x000000010251ad40
0x000000010251ad40
0x000000010251a920
A
これらの変更を有効にすることに関して、私が見逃しているものはありますか?
PS。現在XCode 7.0.1を使用しています