runtime Method Swizzling 예제

3412 단어
이유: 최근에 프로젝트를 볼 때 어떤 인터페이스가 나타났는데 코드가 어디에 있는지 알 수 없기 때문에 이 수요를 달성하기 위해 자연스럽게 사용Method Swizzling되었다. 다음과 같은 코드를 통해 위와 같은 요구를 쉽게 실현할 수 있다.
#import "UIViewController+Swizzling.h"
#import 

@implementation UIViewController (Swizzling)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
     
        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(ypq_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);
        }
    });
}

#pragma mark - Method Swizzling
- (void)ypq_viewWillAppear:(BOOL)animated {
    [self ypq_viewWillAppear:animated];
    NSLog(@"viewApperarClassName===%@", NSStringFromClass([self class]));
}


참고:http://nshipster.com/method-swizzling/
나는 오래된 프로젝트를 사용할 때 한 번 효과가 없는 상황을 만났는데 나중에 발견한 것은 원래 프로젝트에 UIViewController의Category가 이미 있었기 때문에 우리가 가입해서 사용할 때도 이것에 주의해야 한다는 것이다.Method Swizzlingselector의 실제 실현을 바꾸는 기술이다.이 기술을 통해 우리는 실행할 때 클래스의 발표selector에 대응하는 함수를 수정하여 방법을 수정할 수 있다.
확장성
다시 보기 Effective Objective-C 2.0 중의 한 예
#import 

@interface NSString (YPQAddtions)

- (NSString *)ypq_myLowercaseString;

@end


#import "NSString+YPQAddtions.h"

@implementation NSString (YPQAddtions)

- (NSString *)ypq_myLowercaseString {
    NSString *lowercase = [self ypq_myLowercaseString];
    NSLog(@"%@ => %@",self,lowercase);
    return lowercase;
}

@end

위의 코드는 귀속 호출의 사순환에 빠진 것처럼 보이지만, 이 방법은 lowercaseString 방법과 교환할 준비가 되어 있다.따라서 운행기ypq_myLowercaseString에서 서브를 선택하면 실제적으로 기존의 lowercaseString 방법에 대응하여 이루어진다.
//     
Method originalMethod = class_getInstanceMethod([NSString class], @selector(lowercaseString));
Method swappedMethod = class_getInstanceMethod([NSString class], @selector(ypq_myLowercaseString));
method_exchangeImplementations(originalMethod, swappedMethod);

//   

NSString *testString = @"I am A BAd Man";
NSString *lowercaseString = [testString lowercaseString];
NSLog(@"lowercaseString === %@",lowercaseString);

// OutPut
/**
 I am A BAd Man => i am a bad man
 lowercaseString === i am a bad man
 */

이 방안을 통해 우리는 구체적으로 어떻게 이루어졌는지 전혀 모르는 블랙박스 방법에 로그 기록 기능을 추가할 수 있는데 이것은 디버깅에 매우 도움이 된다.
자세한 내용은 아래 링크를 참조하십시오.http://tech.glowing.com/cn/method-swizzling-aop/http://southpeak.github.io/blog/2014/11/06/objective-c-runtime-yun-xing-shi-zhi-si-:method-swizzling/http://blog.csdn.net/yiyaaixuexi/article/details/9374411

좋은 웹페이지 즐겨찾기