相同點:都用來修改現有的類別
不同點:
- Category 只能新增或修改方法,無法新增變數
- Category 中所宣告的方法不用一定要全部實作,但是class extension宣告的方法都必須實現
- Category 方法的implement code必須放在原本類別的.m檔中
- Class extension 所宣告的var and function都是private
使用時機:引用Apple官方文件,“Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation of the class itself.”
以上篇的Dog為基底,我們來擴充一下,新增一個Class extension檔,輸入Extension name
這時候只會產生一個.h檔 Dog_Identification.h,因為要在原本的類別中實作
Dog_Identification.h
括弧內沒有東西,所以這也是為什麼它稱為 匿名的Category的原因。
在原本的Dog.m檔中import此標頭檔,記得不是在Dog.h,因為如果你在Dog.h import Dog_Identificaton.h,又在Dog_Identification.h import Dog.h,這樣互相import會出錯的。
Dog.m
BTW,很多人在使用Class Extension時,是不會去產生一個.h檔的,而是直接在原本類別的.m檔中去做宣告,所以我們這個範例可以改為如下,把Dog_Identification.h刪掉
Dog.m
#import "Dog.h"
@interface Dog ()
{
NSString *_secret;
}
-(NSString *)secret;
-(void)setSecret:(NSString*)s;
@end
括弧內沒有東西,所以這也是為什麼它稱為 匿名的Category的原因。
在原本的Dog.m檔中import此標頭檔,記得不是在Dog.h,因為如果你在Dog.h import Dog_Identificaton.h,又在Dog_Identification.h import Dog.h,這樣互相import會出錯的。
Dog.m
#import "Dog.h" #import "Dog_Identification.h" @implementation Dog -(id)initWithName:(NSString *)name { self = [super init]; if (self) { _name = name; [self setSecret:@"XXX"]; } return self; } -(void)play { NSLog(@"%@ is playing.",_name); } -(NSString *)secret { return _secret; } -(void)setSecret:(NSString*)s { _secret = s; } -(NSString *)giveMeTheSecret { return [self secret]; } @end實作完Class extension functon,另外在Dog.h宣告一個 giveMeTheSecret方法,去調用 -(NSString *)secret 這個private function,因為外部的類別是無法使用private function的。 main.m
#import <Foundation/Foundation.h> #import "Dog.h" #import "Dog+Bark.h" int main(int argc, const char * argv[]) { @autoreleasepool { Dog *d = [[Dog alloc]initWithName:@"Tom"]; [d play]; [d barkWaWa]; [d barkMeMe]; NSLog(@"The secret is %@.",[d giveMeTheSecret]); } return 0; }
BTW,很多人在使用Class Extension時,是不會去產生一個.h檔的,而是直接在原本類別的.m檔中去做宣告,所以我們這個範例可以改為如下,把Dog_Identification.h刪掉
Dog.m
#import "Dog.h" @interface Dog () { NSString *_secret; } -(NSString *)secret; -(void)setSecret:(NSString*)s; @end @implementation Dog -(id)initWithName:(NSString *)name { self = [super init]; if (self) { _name = name; [self setSecret:@"XXX"]; } return self; } -(void)play { NSLog(@"%@ is playing.",_name); } -(NSString *)secret { return _secret; } -(void)setSecret:(NSString*)s { _secret = s; } -(NSString *)giveMeTheSecret { return [self secret]; } @end
沒有留言:
張貼留言