UIViewController에 범주를 사용하여 여러 ViewControllers에서 viewWillAppear : 메서드를 바꿀 수 있습니다.UIViewController 메서드 swizzling 작동하지 않습니다.
@implementation UIViewController (Tracking)
+(void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(xx_viewWillAppear:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod)
{
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}else{
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
-(void)xx_viewWillAppear:(BOOL)animated
{
[self xx_viewWillAppear:animated];
NSLog(@"VC loaded");
}
@end
Storyboard에서 초기 VC를로드 할 때 swizzled 메서드는 호출되지 않습니다. VC의 viewWillAppear 메소드가 주석 처리 된 경우에만 호출됩니다. 그러나 카테고리를 제거하고 코드를 개별 VC로 옮기면 두 메소드가 모두 호출됩니다.
#import "ViewController.h"
#import "UIViewController+Tracking.h"
@interface ViewController()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(@"Inside Controller1");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
swizzled 경우 VC에 viewWillAppear 구현하는 것이 좋습니다 있습니까? 그렇지 않다면 VC의 viewWillAppear에 코드를 작성해야한다면 어떻게해야합니까?
시도 만'method_exchangeImplementations',이 방법은 이미 확장의 일부를 존재, 추가하지 않고. – Cristik
또한 메서드를 기본 클래스에서 swizelling, 사용자 정의 클래스에서 재정의하면 swizzled 메서드를 실행하기 위해'super'를 호출해야 함을 나타냅니다. – Cristik
@Cristik @Cristik 범주를 사용하고 있는데 VC를 서브 클래 싱하지 않습니다. . – KrishnaKumar