- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
//look up method signature
NSMethodSignature *signature = [super methodSignatureForSelector:selector];
if (!signature)
{
//check implementation cache first
NSString *selectorString = NSStringFromSelector(selector);
signature = signatureCache[selectorString];
if (!signature)
{
@synchronized([NSNull class])
{
//check again, incase it was resolved while we were waitimg
signature = signatureCache[selectorString];
if (!signature)
{
//创建一个缓存 获取到所有的类名
//not supported by NSNull, search other classes
if (signatureCache == nil)
{
if ([NSThread isMainThread])
{
cacheSignatures();
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
cacheSignatures();
});
}
}
//遍历缓存,寻找是否已经有可以执行此方法的类
//find implementation
for (Class someClass in classList)
{
if ([someClass instancesRespondToSelector:selector])
{
//其次如果有方法签名返回,runtime则根据方法签名创建描述该消息的NSInvocation,向当前对象发送forwardInvocation:消息,以创建的NSInvocation对象作为参数;
signature = [someClass instanceMethodSignatureForSelector:selector];
break;
}
}
//cache for next time
signatureCache[selectorString] = signature ?: [NSNull null];
}
elseif ([signature isKindOfClass:[NSNull class]])
{
signature = nil;
}
}
}
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
invocation.target = nil;
[invocation invoke];
}
主要方法
int objc_getClassList(Class *buffer, int bufferLen) //获取class列表
获取到,项目中类的所有类名。
static void cacheSignatures()
{
classList = [[NSMutableSet alloc] init];
signatureCache = [[NSMutableDictionary alloc] init];
//get class list
int numClasses = objc_getClassList(NULL, 0);
Class *classes = (Class *)malloc(sizeof(Class) * (unsigned long)numClasses);
numClasses = objc_getClassList(classes, numClasses);
//add to list for checking
for (int i = 0; i < numClasses; i++)
{
//determine if class has a superclass
Class someClass = classes[i];
Class superclass = class_getSuperclass(someClass);
while (superclass)
{
if (superclass == [NSObject class])
{
[classList addObject:someClass];
[classList removeObject:[someClass superclass]];
break;
}
superclass = class_getSuperclass(superclass);
}
}
//free class list
free(classes);
}