Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@leichunfeng
Last active April 6, 2016 04:58
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save leichunfeng/ad7147240f66a9fd03c4 to your computer and use it in GitHub Desktop.
Save leichunfeng/ad7147240f66a9fd03c4 to your computer and use it in GitHub Desktop.
通过重写 NSNull 的消息转发方法,来避免给 [NSNull null] 发消息时的闪退问题
//
// NSNull+LCFMessageForwarding.h
// NSNull
//
// Created by leichunfeng on 15/12/22.
// Copyright © 2015年 leichunfeng. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSNull (LCFMessageForwarding)
@end
//
// NSNull+LCFMessageForwarding.m
// NSNull
//
// Created by leichunfeng on 15/12/22.
// Copyright © 2015年 leichunfeng. All rights reserved.
//
#import "NSNull+LCFMessageForwarding.h"
#import <objc/runtime.h>
@implementation NSNull (LCFMessageForwarding)
+ (void)load {
static dispatch_once_t onceToken1;
dispatch_once(&onceToken1, ^{
Class class = [self class];
SEL originalSelector = @selector(forwardInvocation:);
SEL swizzledSelector = @selector(lcf_forwardInvocation:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (success) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
static dispatch_once_t onceToken2;
dispatch_once(&onceToken2, ^{
Class class = [self class];
SEL originalSelector = @selector(methodSignatureForSelector:);
SEL swizzledSelector = @selector(lcf_methodSignatureForSelector:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (success) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
#pragma mark - Method Swizzling
- (void)lcf_forwardInvocation:(NSInvocation *)anInvocation {
if ([self respondsToSelector:anInvocation.selector]) {
[anInvocation invokeWithTarget:self];
}
}
- (NSMethodSignature *)lcf_methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature *methodSignature = [NSNull instanceMethodSignatureForSelector:aSelector];
if (methodSignature == nil) {
methodSignature = [NSMethodSignature signatureWithObjCTypes:"@^v^c"];
}
return methodSignature;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment