Swizzling没有执行动态方法交换。这个我用过的代码。我听说这是一个解决方案,其中依赖注入无法在xcode 7中的XCTest中进行。你能解释一下关于SD(依赖)的Swizzling的解释吗?
#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未被调用且仅调用实际方法。什么是错的。注意两种方法都是类方法。
答案 0 :(得分:4)
方法实例存在于dispatch表类中,但是 class方法存在于调度表meta_class中 你需要使用元类&#39;而不是自我(阶级)。
#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];
打印&#39; Hello World&#39;
但是你的调酒会影响整个项目。对于这种情况,我建议使用部分模拟(OCMock)