重新認識+和-方法
+:(Class)類方法。
-:(Instance)實例方法。
實質上對于runtime而言,并沒有什么加減號之別。
消息轉發圖.png
對于runtime而言,+號方法和-號方法,都是一樣的方法。
只是+號方法在meta class中查找,而-號方法在class中查找。
注意到Root class(meta)的superclass指向了Root class(class)。
在我們的Root Class正是NSObject。
上圖說明一個問題,如果我們給NSObject發送+號方法,它將在meta class中先查找方法,如果查找不到,會轉到Root class(class)中繼續查找(注意這里面是我們長認為的-號方法)。
代碼驗證:
---------------------------------NSObject(Foo).h
#import <Foundation/Foundation.h>
@interface NSObject (Foo)
//+ (void)foo;
- (void)foo;
@end
---------------------------------NSObject(Foo).m
#import "NSObject+Foo.h"
@implementation NSObject (Foo)
- (void)foo {
NSLog(@"Foo from NSObject(Foo)");
}
//+ (void)foo {
// NSLog(@"Foo from NSObject Class Method");
//}
@end
---------------------------------main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "NSObject+Foo.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
[Person foo];
}
return 0;
}
輸出結果:
Foo from NSObject(Foo)
Person為繼承于NSObject的簡單類,無任何方法實現。
我們并未給NSObject添加+號Class方法foo,但是我們卻可以給NSObject發送該消息,還正確的輸出我們的-號方法實現。
如果我們去掉@implementation NSObject(Foo)中加號+ (void)foo實現的注釋,雖然我們并沒有申明+(void)foo,但是它依然會給NSObject的meta class添加foo方法。此時[Person foo]消息將可以直接在meta class找到foo實現,會輸出:
Foo from NSObject Class Method。