【问题标题】:Swizzling is not working for class methodsSwizzling 不适用于类方法
【发布时间】:2016-01-07 06:40:34
【问题描述】:

Swizzling 不执行动态方法交换。这是我使用的代码。我听说这是一个解决方案,其中依赖注入无法在 xcode 7 的 XCTest 中执行。你能举例说明 Swizzling over DI(Dependency) 吗?

#import "TNUserDetail+Swizzle.h"
#import <objc/runtime.h>

@implementation TNUserDetail (Swizzle)

+ (void) swizzleInstanceSelector:(SEL)originalSelector
                 withNewSelector:(SEL)newSelector
{
    Method originalMethod = class_getClassMethod(self, originalSelector);
    Method newMethod = class_getClassMethod(self, newSelector);

    BOOL methodAdded = class_addMethod([self class],
                                       originalSelector,
                                       method_getImplementation(newMethod),
                                       method_getTypeEncoding(newMethod));

    if (methodAdded) {
        class_replaceMethod([self class],
                            newSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, newMethod);
    }
}

+(BOOL)isSignUpSwizzle {

    return sighUp;
}


Test
_____

@implementation TNSettingsViewControllerTests

- (void)setUp {
    [super setUp];

    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    self.settingVC = [sb instantiateViewControllerWithIdentifier:@"TNSettingsViewController"];


    [self.settingVC performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES];
    [self.settingVC performSelectorOnMainThread:@selector(viewWillAppear:) withObject:nil waitUntilDone:YES];
}

-(void)testTwitterConnectSwitchValueChanged
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        [TNUserDetail swizzleInstanceSelector:@selector(isSignUpWithTwitter) withNewSelector:@selector(isSignUpSwizzle)];
        [TNUserDetail isSignUpWithTwitter];
    });

    sighUp = YES;
    self.settingVC.twitterConnectSwitch.on = YES;
    [self.settingVC.twitterConnectSwitch sendActionsForControlEvents:UIControlEventValueChanged];;
}

这里当我调用 [TNUserDetail isSignUpWithTwitter] 时,+(BOOL)isSignUpSwizzle 没有被调用,只有实际的方法被调用。怎么了。注意这两种方法都是类方法。

【问题讨论】:

    标签: ios objective-c swizzle


    【解决方案1】:

    方法实例存在于调度表类中,但是 调度表 meta_class 中存在类方法,所以 您需要使用“元类”而不是 self(class)。

    #import "TNUserDetail.h"
    #import <objc/runtime.h>
    
    @implementation TNUserDetail
    
    + (void)swizzleInstanceSelector:(SEL)originalSelector withNewSelector:(SEL)newSelector {
        const char *className = [NSStringFromClass(self) UTF8String];
        Class clazz = objc_getMetaClass(className);
        Method originalMethod = class_getClassMethod(clazz, originalSelector);
        Method newMethod = class_getClassMethod(clazz, newSelector);
    
        BOOL methodAdded = class_addMethod(clazz,
                                           originalSelector,
                                           method_getImplementation(newMethod),
                                           method_getTypeEncoding(newMethod));
    
        if (methodAdded) {
            class_replaceMethod(clazz,
                                newSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, newMethod);
        }
    }
    
    + (void)load {
        [super load];
        [self swizzleInstanceSelector:@selector(printHello) withNewSelector:@selector(printHelloWorld)];
    }
    
    + (void)printHello {
        NSLog(@"Hello");
    }
    
    + (void)printHelloWorld {
        NSLog(@"Hello World");
    }
    
    @end
    

    并调用[TNUserDetail printHello]; print 'Hello World'

    但是您的调酒会影响整个项目。对于这种情况,我建议使用部分模拟 (OCMock)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2020-04-25
      相关资源
      最近更新 更多