0

メソッドスウィズリングを実行するための次のコードがあります。

static inline void swizzleMethod(const char *clsName, const char *mthName, const char *clsName2, const char *mthName2) {
    Class cls1 = objc_getClass(clsName);
    SEL sel1 = sel_registerName(mthName);

    Class cls2 = objc_getClass(clsName2);
    SEL sel2 = sel_registerName(mthName2);
    Method mth = class_getInstanceMethod(cls2, sel2);
    IMP imp = method_getImplementation(mth);
    NSLog(@"method type encoding %s", method_getTypeEncoding(mth));

    class_replaceMethod(cls1, sel1, imp, method_getTypeEncoding(mth));
}

私のVGFileHandleクラス:

@interface VGFileHandle : NSObject
@end

@implementation VGFileHandle
- (NSData *)readDataToEndOfFile {
    NSLog(@"readDataToEndOfFile");
    return nil;
}
@end

main.mには、次の呼び出しがあります。

int main(int argc, char *argv[])
{    
    swizzleMethod("NSFileHandle", "readDataToEndOfFile", "VGFileHandle", "readDataToEndOfFile");

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"myFile"];

    NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:filePath];
    NSData *data = [handle readDataToEndOfFile];

    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

当然、[handle readDataToEndOfFile]が呼び出されると、VGFileHandleからreadDataToEndOfFileを呼び出し、「readDataToEndOfFile」を出力する必要があります。しかし、私のテストプロジェクトでは、メソッドのスウィズリングがメソッドの実装にまったく取って代わっていないようです。[handle DataToEndOfFile]は、元の実装を引き続き実行します。

その理由を知りたいのですが。前もって感謝します。

4

2 に答える 2

2

NSFileHandleの実装を見ずに、明確に言うことは不可能です。

ほとんどの場合、NSFileHandleがクラスクラスターとして実装されているため、実際には抽象、パブリック、クラスのインスタンスがありません。代わりに、いくつかのプライベートサブクラスのインスタンスがあります(これは、一見ランダムで、実装の詳細を重視し、OSのリリースまたは構成全体で理由が変わる可能性があります)。

Swizzlingメソッドは悪いコードです。プライベートシステムクラスのスウィズリングメソッドはコードが悪く、デバッグとサポートの問題を引き起こすことがほぼ保証されています。

于 2013-01-25T15:00:23.580 に答える
1

[NSFileHandle fileHandleForReadingAtPath:filePath]は、NSFileHandleではなくNSConcreteFileHandleのインスタンスを返します。

代わりにこれを呼び出す必要があります:

swizzleMethod("NSConcreteFileHandle", "readDataToEndOfFile", "VGFileHandle", "readDataToEndOfFile");
于 2013-03-19T08:43:16.063 に答える