相同點:都用來修改現有的類別
不同點:
- 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



沒有留言:
張貼留言