你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> ios 中Category類別(擴展類)專題總結

ios 中Category類別(擴展類)專題總結

編輯:IOS開發綜合

 

 

類別

類別是一種為現有的類添加新方法的方式。
利用Objective-C的動態運行時分配機制,可以為現有的類添加新方法,這種為現有的類添加新方法的方式稱為類別catagory,他可以為任何類添加新的方法,包括那些沒有源代碼的類。
類別使得無需創建對象類的子類就能完成同樣的工作
一、創建類別
1、聲明類別
聲明類別與聲明類的形式很相似
@interface NSString(NumberConvenience)
-(NSNumber *)lengthAsNumber;
@end//NumberConvenience
這個聲明有兩個特點:
(1)現有的類位於@interface關鍵字之後,其後是位於圓括號中的類別名稱。類別名稱是NumberConvenience,而且該類別將向NSString類中添加方法。換句話說:“我們向NSString類中添加一個名稱為NumberConvenience的類別。”
同名類別有唯一性,但是可以添加任意多的不同名類別。
(2)可以執行希望向其添加類別的類以及類別的名稱,還可以列出添加的方法
不可以添加新的實例變量,類別生命中沒有實例變量部分。
2、實現類別
@implementation NSString(NumberConvenience)
-(NSNumber *)lengthAsNumber
{
unsigned int length = [self length];
return ([NSNumber numberWithUnsignedInt : length]);
} //lengthAsNumber
@end //NumberConvenience
在實現部分也包括類名、類別名和新方法的實現代碼
3、類別的局限性
有兩方面局限性:
(1)無法向類中添加新的實例變量,類別沒有位置容納實例變量。
(2)名稱沖突,即當類別中的方法與原始類方法名稱沖突時,類別具有更高的優先級。類別方法將完全取代初始方法從而無法再使用初始方法。
無法添加實例變量的局限可以使用字典對象解決
4、類別的作用
類別主要有3個作用:
(1)將類的實現分散到多個不同文件或多個不同框架中。
(2)創建對私有方法的前向引用。
(3)向對象添加非正式協議。

二、利用類別分散實現
我們可以將類的接口放入頭文件中,從而將類的實現放入.m文件中
但不可以將@implementation分散到多個不同的.m文件中,使用類別可以完成這一工作
利用類別,可以將一個類的方法組織到不同的邏輯分組中,使編程人員更加容易的閱讀頭文件
舉例代碼:
頭文件CatagoryThing.h包含類的聲明和一些類別,導入Foundation框架,然後帶有3個整型變量的聲明
#import
@interface CategoryThing : NSObject {
int thing1;
int thing2;
int thing3;
}
@end // CategoryThing
類聲明之後是3個類別,每個類別具有一個實例變量的訪問器,將這些實現分散到不同的文件中
@interface CategoryThing(Thing1)
- (void) setThing1: (int) thing1;
- (int) thing1;
@end // CategoryThing (Thing1)

@interface CategoryThing (Thing2)
- (void) setThing2: (int) thing2;
- (int) thing2;
@end // CategoryThing (Thing2)

@interface CategoryThing (Thing3)
- (void) setThing3: (int) thing3;
- (int) thing3;
@end // CategoryThing (Thing3)

類別可以訪問其繼承的類的實例變量,類別的方法具有最高的優先級
類別可以分散到不同文件中,甚至不同框架中

三、使用類別創建前向引用
如果其他類中的方法未實現,在你訪問其他類的私有方法時編譯器報錯
這時使用類別,在類別中聲明這些方法(不必提供方法實現),編譯器就不會再產生警告

四、非正式協議和委托類別
Cocoa中的類經常使用一種名為委托(delegate)的技術
委托是一種對象,另一個類的對象會要求委托對象執行他的某些操作
(看不懂,在實踐中學習)
#import #import ITunesFinder.h int main (int argc, c*****t char *argv[]) { NSAutoreleasePool *pool; pool = [[NSAutoreleasePool alloc] init]; NSNetServiceBrowser*browser; browser = [[NSNetServiceBrowseralloc] init]; ITunesFinder *finder; finder = [[ITunesFinder alloc] init];//因為finder是alloc方法創建的,必須在不適用這個對象時將其釋放
[browser setDelegate:finder];//告知browser使用finder作為委托對象 [browser searchForServicesOfType: @_daap._tcp //告知browser對象使用TCP協議去搜索DAAP類型服務 inDomain: @local.];//表示只搜索本地 NSLog (@begun browsing);//表示下面的run循環已經開始 [[NSRunLoop currentRunLoop] run];//run循環是一種Cocoa構造,他不執行任何處理,等待用戶的操作 [browser release];//run方法將一直保持運行而不返回,所以包含此行之後的代碼不會被運行 [finder release]; [pool release]; return (0); } // main

創建一個NSObject的類別稱為“創建一個非正式協議”,因為可以作為任何類的委托對象使用

響應選擇器
選擇器只是一個方法名稱,但它以Objective-C運行時使用特殊方式編碼,以快速執行查詢
可以使用@selector()預編譯指定選擇器,其中方法名位於圓括號中
例如之前的Car類的setEngine:方法的選擇器是:@selector(setEngine:)
而Car類的setTire:atIndex;方法的選擇器如下所示:@selector(setTire:atIndex;)

NSObject提供了一個名為respondsToSelector方法,該方法詢問對象以確定其是否能夠響應某個特定的消息
舉例代碼:
Car *car = [[Car alloc] init];
if([carrespondsToSelector:@selector(setEngine:)]){
NSLog(@hihi);

}
選擇器的其他應用
選擇器可以被傳遞,可以作為方法的參數使用,甚至可以作為實例變量存儲

小結
類別提供了向現有類添加新方法的手段,即使沒有這些類的源代碼
類別可以將對象的實現分散到多個不同的源文件、甚至多個不同的框架中
使用類別可以聲明非正式協議,非正式協議是NSObject的一個類別,他可以列出對象能夠響應的方法
非正式協議用於委托,委托是一種允許輕松定制對象行為的技術




類別是一種為現有的類添加新方法的方式。

@interface NSString (NumberConvenience)
- (NSNumber *)lengthAsNumber;
@end
(1)為NSString類添加一個名稱為NumberConveniencede的類別;類別名稱具有唯一性,你可以向一個類中添加任意多的類別。
(2)可以指定希望向其添加類別的類(NSString),以及類別的名稱(NumberConvenience),而且你還可以列出添加的方法,最後以@end結束;類別聲明部分不能有實例變量部分
實現類別
@implementation NSString (NumberConvenience)
- (NSNmuber *)lengthAsNumber{
unsigned int length = [self length];//獲得字符串長度
return ([NSNumber numberWithUnsignedInt :length]);

@end
#import
#import CategoryThing.h
//類別的作用:
//(1)將類別實現分散到多個不同文件或多個不同框架中
//(2)創建私有方法的前向引用
//(3)向對象添加非正式協議
//類別的局限性:
//(1)無法添加新的實例變量
//(2)名稱沖突,如果類別和現有的方法重名,類別具有更高的優先級,解決辦法,類別方法名中添加一個前綴
@interface NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber;
@end
@implementation NSString (NumberConvenience)
- (NSNumber *) lengthAsNumber
{
unsigned int length= [self length];
return ([NSNumber numberWithUnsignedInt:length]);
}
@end
int main (int argc, c*****t char * argv[]) {
//我們適用類別創建的所有NSNumber類的對象將在自動釋放池中被銷毀一樣,可變字典也將在這裡被銷毀
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...

NSMutableDictionary *dict;
dict=[NSMutableDictionary dictionary];

//使用鍵@“hello”將整值5添加到字典中的代碼如下
[dict setObject:[@hello lengthAsNumber] forKey: @hello];

[dict setObject:[@iLikeFish lengthAsNumber] forKey: @iLikeFish];

[dict setObject:[@Once upon a time lengthAsNumber] forKey: @Once upon a time];

NSLog(@%@,dict);

CategoryThing *thing;
thing= [[CategoryThing alloc] init];

[thing setThing1:5];
[thing setThing2:23];
[thing setThing3:42];

NSLog(@Thing are %@!,thing);

[thing release];

[pool drain];
return 0;
}
//
// CategoryThing.h
// S12_leibie
//
// Created by cwity on 11-5-17.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import
@interface CategoryThing : NSObject {
int thing1;
int thing2;
int thing3;
}
@end
@interface CategoryThing (Thing1)
- (void) setThing1:(int) thing1;
- (int) thing1;
@end
@interface CategoryThing (Thing2)
- (void) setThing2:(int) thing2;
- (int) thing2;
@end
@interface CategoryThing (Thing3)
- (void) setThing3:(int) thing3;
- (int) thing3;
@end
//
// CategoryThing.m
// S12_leibie
//
// Created by cwity on 11-5-17.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import CategoryThing.h
@implementation CategoryThing
- (NSString *) description
{
NSString *desc;
desc= [NSString stringWithFormat:@%d %d %d,
thing1,thing2,thing3];

return (desc);
}
@end
//
// Thing1.m
// S12_leibie
//
// Created by cwity on 11-5-17.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import CategoryThing.h
@implementation CategoryThing (Thing1)
- (void) setThing1:(int)t1
{
thing1=t1;
}
- (int) thing1
{
return (thing1);
}
@end
//
// Thing2.m
// S12_leibie
//
// Created by cwity on 11-5-17.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import CategoryThing.h
@implementation CategoryThing (Thing2)
- (void) setThing2:(int)t2
{
thing2=t2;
}
- (int) thing2
{
return (thing2);
}
//
// Thing3.m
// S12_leibie
//
// Created by cwity on 11-5-17.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#importCategoryThing.h
@implementation CategoryThing (Thing3)
- (void) setThing3:(int)t3
{
thing3=t3;
}
- (int) thing3
{
return(thing3);
}
@end


objective-c中類別(擴展類)專題總結 什麼時候使用類別?
(1)類別只能添加新方法,無法添加新的實例變量(2)如果類別名和原來類中的方法產生名稱沖突,則類別將覆蓋原來的方法,因為類別具有更高的優先級。
要注意的是Objective-c只支持單繼承,如果要實現多繼承的話,可以通過類別和協議的方式來實現。

另外要特別注意的是,類別不能像繼承時那樣給類別接口增加新的實例變量,而是要擴展一個類的行為。
類別的名稱是任意的。


創建類別
類別是一種為現有的類添加新方法的方式。 類別有兩方面的局限性。第一,無法向類中添加新的實例變量。類別沒有位置容納實例變量。 第二,名稱沖突,即類別中的方法與現有的方法重名。當發生名稱沖突時,類別具有更高的優先級。你的類別方法將完全取代初始方法,從而無法再使用初始方法。有些編程人員在自己的類別方法名中增加一個前綴,以確保不發生名稱沖突。 說明 也有一些技術可以克服類別無法增加新實例變量的局限。例如,可以使用全局字典存儲對象與你想要關聯的額外變量之間的映射。但此時你可能需要認真考慮一下,類別是否是完成當前任務的最佳選擇。 的作用 Cocoa中的類別主要用於3個目的:將類的實現分散到多個不同文件或多個不同框架中,創建對私有方法的前向引用,以及向對象添加非正式協議。如果你還不理解“非正式協議”(informal protocol)的含義,請不要擔心,我們稍後將簡單地討論這一概念。



Objective-C 類的繼承、方法重載
這次,我們講解在Objective-C中如何進行類的繼承以及方法的重載。按照慣例,我們還是先拿出一個重載的小例子,以例子為基礎展開講解。
#import
@interface ClassA:NSObject //ClassA類型繼承NSObject類型
{
int x; //聲明變量成員
}
-(void) initVar; //聲明初始化方法
@end
@implementation ClassA //定義ClassA
-(void) initVar //定義初始化方法
{
x = 100;
}
@end

@interface ClassB:ClassA //ClassB類型繼承ClassA類型
-(void) initVar; //聲明初始化方法,此方法重載ClassA中的同名方法
-(void) printVar; //聲明打印變量方法
@end
@implementation ClassB //定義ClassB
-(void)initVar //定義初始化方法
{
x = 200;
}
-(void) printVar //定義打印變量方法
{
NSLog(@x = %i, x);
}

int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ClassB *b = [[ClassB alloc]init]; //定義ClassB類型實例
[b initVar]; //調用b對象的initVar方法
[b printVar]; //調用b對象的printVar方法
[b release]; //釋放b對象占用的內存空間
[pool drain];
return 0;
}
-------------------------------------------------------------------------------
輸出:
x = 200;
-------------------------------------------------------------------------------

接觸過C++的同學看過上面的小例子,立刻就明白了,其實Objective-C的繼承和C++繼承的語法很類似,差別很小,都是在聲明類型的時候多加一句代碼,如ClassB類型繼承ClassA類型,即在定義接口文件時編寫:@interface ClassB:ClassA,即可完成繼承。順便提一句,Objective-C不能直接進行多繼承,需要輔助協議(協議本質上類似與C#語言中的接口。關於協議的具體內容,將會在後面和分類概念一起介紹)實現多繼承。
Objective-C中的方法重載也很簡單,只要子類中的方法名稱和父類的方法名稱一樣,即可自動對父類的同名方法進行重載,不用添加任何關鍵字。




Objective-C學習筆記---類別(實現多重繼承的方法)
? 類別是一個類,它是添加了新功能的現有類。
? 使用類別就是為了能夠為現有類添加新的方法,不用繼承該現有類,就可使用現有類的對象調用添加的方法了。
? 類別可以使類的實現分散在多個文件中.
? 類別中不能有變量,類別中沒有放變量的位置.
? 如果類中的方法和類別中的方法名稱相同,這將造成沖突,類別的方法將完全取代類的方法。
? 同一個類的不同類別聲明了相同的方法,這將導致不穩定,哪個方法會被調用是不確定的.

類別聲明:
#import ClassName.h
@interface ClassName ( CategoryName )
方法聲明
@end
類別實現:
#import ClassName+CategoryName.h” //聲明文件
@implementation ClassName ( CategoryName )
方法實現
@end
實例:
FractionMath.h
#import Fraction.h
@interface Fraction (Math)
-(Fraction*) add: (Fraction*) f;
-(Fraction*) mul: (Fraction*) f;
-(Fraction*) div: (Fraction*) f;
-(Fraction*) sub: (Fraction*) f;
@end
FractionMath.m
#import FractionMath.h
@implementation Fraction (Math)
-(Fraction*) add: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f denominator] +denominator *
[f numerator] denominator: denominator * [f denominator]];
}
-(Fraction*) mul: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f numerator]
denominator: denominator * [f denominator]];
}
-(Fraction*) div: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f denominator]
denominator: denominator * [f numerator]];
}
-(Fraction*) sub: (Fraction*) f {
return [[Fraction alloc] initWithNumerator: numerator * [f denominator] -denominator * [f numerator]
denominator: denominator * [f denominator]];
}
@end
main.m
#import
#import Fraction.h
#import FractionMath.h
int main( int argc, c*****t char *argv[] ) {
// create a new instance
Fraction *frac1 = [[Fraction alloc] initWithNumerator: 1 denominator: 3];
Fraction *frac2 = [[Fraction alloc] initWithNumerator: 2 denominator: 5];
Fraction *frac3 = [frac1 mul: frac2];
[frac1 print];
printf( * );
[frac2 print];
printf( = );
[frac3 print];
printf( /n );
// free memory
[frac1 release];
[frac2 release];
[frac3 release];
return 0;
}



類別 (又叫類的擴展)
@interface 類名 (類別名) //類別名可以隨便取
例如:在.m文件中這樣寫。 @interface TEST_DRAW_APPViewController (ViewHandlingMethods) //此處是類別,又叫類擴展
類別要解決的問題是:為現有的類增加新行為
子類是一種辦法,但是面對類簇和工具包或類庫時確沒有能力為力
類別解決了這個問題。
創建類別:類別是一種為現有類提供新方法的方式。
類別與擴展
category 下稱類別允許你甚至在沒有類源碼的情況下擴展一個類的功能,給它增加方法。
主要作用是使相同的方法在沒有繼承關的類中復用。
。對框架提供類的擴展(沒有源碼,不能修改)。
2。 不想生成一個新的子類的情況下,比如對 NSArray 的擴展。
3。 方便做項目管理,可以將一份源碼在多個地方共享或者做方法版本管理、多人協作開發、用本地版本替換公共版本實現。
不建議在 category 中覆蓋類中的方法,因為在 category 中的方法不能調用 superClass 的方法(因為沒有元數據支持)
category 方法不能覆蓋於同一class 的其它 category 中的方法。因為不法預知他們的加載優先順序,就可能在編譯時出錯。
對類庫的 category 方法覆蓋對導致整個類庫的行為發生變化,因此調用那些方法的類不知道方法的實現已經發生了變化。
警告:
雖然 category 不限於任何 class ,但是仍然不建議編寫針對 rootClass 的 category。 原因是影響面較大,其它開發人員如果不注意的話就會出問題。
而且類對象也可能調用這些方法,甚至在調用時的 self 指針不是實例而是類對象本身。
類別的作用
通過類別的方式,可以將類的實現分散到不同的文件裡。



Objective-C 2.0中的Category語法 ,Category提供了一種比繼承(inheritance)更為簡潔的方法來對class進行擴展,我們可以為任何已經存在的class添加方法。
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved