第九章 Foundation框架中常用的類

OC中的類分為可變和不可變。下表列出了Foundation框架中主要的可變類和不可變類:

種類

不可變類

可變類

數組

NSArray

NSMutableArray

數據

NSData

NSMutableData

詞典

NSDictionary

NSMutableDictionary

集合

NSSet

NSMutableSet

字符串

NSString

NSMutableString

帶屬性的字符串

NSAttributedString

NSMutableAttributedString

字符集合

NSCharacterSet

NSMutableCharacterSet

索引集合

NSIndexSet

NSMutableIndexSet

可變對象的生成:

可變類是不可變類的子類,所以可變類的實例對象可直接作為不可變類的實例對象。與此相反,如果想把不可變類的實例對象作為可變類的實例對象來使用的話,可以使用mutableCopy方法位不可變對象創建一個可變的副本。

- (id)mutableCopy

字符串類NSString

常量字符串:

NSString*name =@"chenzhen”;

使用這種方式定義的字符串是常量對象,可被作為NSString的對象使用。既可以做消息的參數,又可以做消息的接收者。

@“”表示空字符串,但和nil有區別。

編譯器編譯時會把用空格分割的字符串連在一起:

NSString*name =@"chen"@" "@"zhen”;

字符串常量從程序的執行開始到終止一直存在,調用release或者垃圾回收都不能釋放字符串常量。

NSString:

NSString和NSMutableString的實例稱為字符串對象或者字符串。字符串對象內部使用Unicode編碼。

將字符串作為對象來處理的優點:

可以統一很多的操作

生成釋放的邏輯相同

NSString還定義了很大常用的方法

由于NSString是以類簇的方式實現的,因此不能用常用的方法來為NSString定義子類。

在初始化方法的說明中,使用alloc和init的組合生成并返回實例的類方法都被標記為了便利構造函數。下面對NSString的主要方法進行說明:

(1)操作Unicode編碼的字符串

NSString中的漢字都是用Unicode來表示的。Unicode的UTF-8編碼兼容ASCII的7bit編碼,字符串中只含有ASCII的7bit范圍的編碼情況下,ASCII的字符串可被當作UTF-8的Unicode字符串來處理,不能被當作UTF-16的字符串來處理。

- (

id)initWithUTF8String:(constchar*)bytes//從以Null結束的UTF-8編碼的c字符串中復制信息,并初始化接收者。便利構造器:stringWithUTF8String:

- (

__strongconstchar*)UTF8String//返回編碼為UTF,以NULL結尾的c語言字符串的指針。基于引用計數的內存管理模式下,返回的字符串會在消息接收對象被釋放的同時被釋放掉。垃圾回收的內存管理模式下,因為返回的是強指針,所以不會被垃圾回收。

- (NSUInteger)length

//返回字符的個數。

- (unichar)characterAtIndex:(NSUInteger)index

//返回索引為i的字符。unichar是兩字節長的char,代表unicode的一個字符。

- ?(id)initWithCharacters:(const unichar *)characters length:(NSUInteger)length

//用characters中存儲的length長的字符串來初始化并返回一個NSString對象,初始化以length為準,characters中就算包括‘\0’也不能作為終止標記。便利構造器:stringWithCharacters:length

- ?(void)getCharacter:(unichar *)buffer range(NSRange)aRange

//NSRange是一個表示范圍的結構體,其中包括數據的首指針和數據長度。這個函數的作用就是將aRange所表示的字符串作為Unicode字符串寫入緩沖區buffer,末尾不自動添加NULL,緩沖區需要足夠大。

(2)編碼轉換

C風格或字節類型的字符串和NSString之間可以相互轉換。字符串編碼定義為枚舉類型NSStringEncoding。

- (id)initWithCString:(constchar*)nullTerminatedCString

encoding:(NSStringEncoding)encoding

//用C風格字符串初始化一個NSString對象,字符串nullTerminatedCString要求以NULL結尾,編碼為encoding。便利構造器:stringWithCString:encoding

- (__strongconstchar*)cStringUsingEncoding:(NSStringEncoding)encoding//返回消息接收對象的C風格字符串,編碼由encoding指定。基于引用計數的內存管理模式下,返回的字符串會在消息接收對象被釋放的同時被釋放掉。垃圾回收的內存管理模式下,因為返回的是強指針,所以不會被垃圾回收。

- (id)initWithData:(NSData *)data

encoding:(NSStringEncoding)encoding

//用存儲在data中的二進制數據來初始化NSString對象。

- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding

//接收消息的NSString對象的內容用encoding指定的方法編碼,并將結果存儲到一個NSData對象中并返回。

- (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding//測試接收消息的NSString對象能否轉換為encoding編碼。使用類方法availableStringEncodings能夠返回當前環境下可以用的編碼方式。

-(NSString*)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding

//能夠對一些特殊字符進行替換,主要被用于處理URL字符串,比如將空格替換成%20等。stringByReplacingPercentEscapesUsingEncoding:是上述方法的逆變換。

(3)生成指定格式的字符串

%@對應的參數必須是一個對象。當輸出%@時(例如:NSLog(@“%@“, test)),實際上就是調用了test的description方法,返回結果存儲到%@中。NSString不支持參數類型自動轉換,所以要保證指定的類型和所傳入的參數的類型一致。

- (id)initWithFormat:(NSString *)format ,...//根據format中指定的格式串來生成一個字符串,使用這個字符串初始化消息接收者。format中的參數用逗號分隔,格式字符串不能為空。便利構造器:stringWithFormat:

(4)NSString的比較

字符串比較時會返回一個NSComparisonResult類型的值,它是enum型的數據,共有三個值,分別為NSOrderedAscending,NSOrderedSame,NSOrderedDescending.

- (NSComparisonResult)compare:(NSString *)aString//區分大小寫的比較

- (NSComparisonResult)caseInsensitiveCompare:(NSString *)aString

//不區分大小寫的比較

- (NSComparisonResult)localizedStandardCompare:(NSString *)aString

//按照Mac系統的Finder的排序規則進行比較操作。

- (

BOOL

)isEqualToString:(NSString *)aString

- (

BOOL)hasPrefix:(NSString *)aString//檢查字符串是否以aString開頭。另外還可以使用方法commonPrefixWithString:options:來取出消息接收者和參數字符串開頭部分相同的字符串。

(5)為字符串追加內容

- (NSString *)stringByAppendingString:(NSString *)aString

- (NSString *)stringByAppendingFormat:(NSString *)format

//在接收者字符串后面追加格式化字符串,字符串的具體格式又format指定,然后返回一個新的字符串。

(6)截取字符串

截取指定的字符串并返回。使用結構體NSRange來表示要截取的字符串的開始位置和長度。

- (NSString *)substringToIndex:(NSUInteger)anIndex//返回一個新的字符串,新字符串的范圍是從接收者字符串的第一個字符開始到anIndex結束,anIndex不包含在內

- (NSString *)substringFromIndex:(NSUInteger)anIndex

//返回一個新的字符串,新字符串的范圍是從anIndex開始一直到結尾,anIndex位置的字符也包含在內。

- (NSString *)substringWithRange:(NSRange)aRange

//返回新字符串的開始位置和長度由aRange來指定。

(7)檢索和置換

- (NSRange) rangeOfString:(NSString *)aString//查找到aString則返回aString的位置和長度。如果沒有找到,返回一個位置為NSNotFound,長度為0的NSRange類型的對象。

- (NSRange)lineRangeForRange:(NSRange)aRange

//返回NSRange所在行的范圍。

- (NSString *)stringByReplacingCharactersInRange:(NSRange)aRange

withString:(NSString *)replacement

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target

withString:(NSString *)replacement

(8)大小寫的處理

可以使用lowercaseString方法將字符串中所有的大寫字母都轉化為小寫,與此相對,uppercaseString。除了這兩個之外,方法capitalizedString能夠將所有單詞的首字母變為大寫,其余字母變為小寫。

(9)數值轉換

方法doubleValue可把NSString類型的字符串轉為double類型的數值。類似的還有floatValue,intValue,integerValue,boolValue.另外當輸入的字符串首字母是Y,y,T,t中的任何一個,或者是不以0開頭的數字時,方法boolValue都會返回YES。

(10)路徑處理

文件的路徑可用NSString來表示。Unix中使用“/”作為路徑分割符。方法NSHomeDirectory()能夠返回當前用戶的主目錄。以文件路徑名@“tmp/image/cat.tif”為例。

- (NSString *)lastPathComponent//提取文件路徑中最后一個組成部分,上面例子會返回“cat.tiff”。

- (NSString *)stringByAppendingPath:(NSString *)aStr

//將aStr加到現有字符串的末尾并返回,根據需要會自動追加分隔符。

- (NSString *)stringByDeletingLastPathComponent

//刪除路徑中最后一個組成部分,如果返回的結果不是根路徑,那么最后的路徑分隔符也會被刪除。

- (NSString *)pathExtension

//返回文件擴展名,不包含“.”。沒有擴展名返回空字符串。

- (NSString *)stringByAppendingPathExtension:(NSString *)aString

//將“.”和指定擴展名添加到現有路徑的最后一個組成部分。

- (NSString *)stringByDeletingPathExtension

//刪除文件擴展名,包括“.”,沒有擴展名則返回原來的字符串。

- (

BOOL)isAbsolutePath//判斷路徑是不是一個絕對路徑,如果是則返回YES。

+ (NSString *)pathWithComponents:(NSArray *)components

//使用components中的元素來構建路徑,結合的時候自動添加路徑分隔符”/“。想生成一個絕對路徑的話,數組中的第一個元素使用@”/“。路徑的最后想要以路徑分隔符結尾的話,數組的最后一個元素使用空字符串@”“。

- (NSArray *)pathComponents

//和pathWithComponents:正好相反。

- (NSString *)stringByExpandingTildeInPath

//如果路徑的第一個字符是代字符(以~開頭的,例如:~/),則返回用戶主目錄的路徑字符串。否則,直接返回輸入的字符串。stringByAbbreviatingWithTildeInPath的功能正好相反,會把標準格式的字符串轉換為使用代字符的字符串。

- (

__strongconstchar*)fileSystemRepresentation//返回路徑的C風格字符串,使用當前系統編碼。

(11)文件的輸入和輸出

- (

id

)initWithContentsOfFile:(NSString *)path

encoding:(NSStringEncoding)enc

error:(NSError **)error

//通過讀取文件path中的內容來初始化一個NSString,文件的編碼為enc。讀取文件失敗會釋放調用者,并在返回nil的同時將詳細的錯誤信息設定到error。便利構造器:stringWithContentsOfFile:encoding:error:

- (

id

)initWithContentsOfFile:(NSString *)path

usedEncoding:(NSStringEncoding *)enc

error:(NSError **)error

//和上一個方法不同的地方在于這個函數能夠自動判別文件的編碼,并通過enc返回。文件的編碼是通過文件的內容和擴展屬性來判斷的。便利構造器:stringWithContentsOfFile:usedEncoding:error:

- (

BOOL

)writeToFile:(NSString *)path

atomically:(

BOOL

)useAuxiliaryFile

encoding:(NSStringEncoding)enc

error:(NSError **)error

//用于將字符串的內容寫入到path為路徑的文件中,寫入的時候使用enc指定的編碼,寫入成功則返回YES。useAuxiliaryFile為YES的情況下,會首先新建一個臨時文件,把字符串的內容寫入到臨時文件中。然后再在寫入成功后把臨時文件重命名為path指定的文件。這種方法寫入發生錯誤時不會損壞原來的文件。為NO時,則直接將字符串內容輸入到path指定的文件中。如果寫入失敗,則會在返回NO的同時把出錯的原因寫入到error中,并返回給函數調用者。

(12)其他

- (id)init//對接收者進行初始化,并返回一個空字符串。通常被用于NSMutableString的初始化。便利構造器:string。

- (

id)initWithString:(NSString *)aString//返回一個字符串對象,其內容是aString的副本。aString也可以是NSMutableString的實例對象。用這個方法可以用一個可變的字符串對象生成一個不可變的字符串對象。便利構造器:stringWithString:

- (NSString *)description

//返回消息接收者內容的字符串。NSString的description方法會直接返回self。

- (

id)propertyList//返回消息接收者的屬性列表。

- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)sep

//用參數sep指定的字符集合中的字符作為分隔符,對消息接收者字符串進行分割,并返回分割后生成的字符串數組。

NSMutableString:

NSMutableString是NSString的子類,所以可以使用NSString中定義的所有方法。下面對NSString中未定義的方法進行說明:

(1)實例對象的生成和初始化

- (id)initWithCapacity:(NSUInteger)capacity//初始化一個NSMutableString類型的對象,capacity指明了要被初始化的NSMutableString對象的大小.NSMutableString的對象會隨著字符串的變化而自動擴展內存,所以capacity不需要非常精密。除了這個方法之外,還可以使用NSString的init方法或NSString的類方法string:來生成一個空的NSMutableString對象。便利構造器:stringWithCapacity:

(2)追加字符串

- (void)appendString:(NSString *)aString//在消息接收者的末尾追加aString。

- (

void)appendFormat:(NSString *)format,……//在消息接收者的末尾遍加format格式的格式化字符串。

(3)插入刪除置換

- (void

)insertString:(NSString *)aString

atIndex:(NSUInteger)loc

//在消息接收者的atlndex位置插人字符串aString。

- (

void)deleteCharactersInRange:(NSRange)range//結構體NSRange表示一個范圍,其中包含了開始位置和長度,這個方法的作用是從接收者中刪除aRange指定范圍內的字符串。

- (

void)setString:(NSString *)aString//復制aString指定的字符串,并將其設置為消息接收者的內容。

- (

void

)replaceCharactersInRange:(NSRange)aRange

withString:(NSString *)aString

//把aRange指定范圍內的字符內容替換為aString指定的字符串。

- (NSUInteger)replaceOccurrencesOfString:(NSString *)target

withString:(NSString *) replacement.

options:(NSStringCompareOptions)opts

range:(NSRange)searchRange

//searchRange指定范圍內如果存在字符串target,就將其替換為replacement。這個函數的返回值就是替換的次數。使用選項opts可以設置忽略大小寫,或者使用正則表達式進行替換等。

NSData

NSData:

NSData是Cocoa下對二進制數據的一個封裝,能夠把二進制數據當作對象來處理。

同C語言的數組相比,NSData的優點是可以進行更抽象話的操作,使內存管理更容易,同時也是cocoaAPI中操作二進制數據的標準。

NSData是不可變的,所以實例對象一旦創建之后就不可改變其內容。而如果想改變數據的內容,就需要使用將在后面介紹的類NSMutableData。NSData和NSMutableData的實例對象有時也稱為數據對象。

NSData的接口文件定義在Foundation/NSData.h中。NSData是以類族的方式實現的,所以不能用通常的方法來為NSData定義子類下面介紹了類NSData的幾個主要方法,如果想了解全部方法,請參考蘋果公司的文檔。

(1)數據對象的生成和初始化

- (id)initWithBytes:(constvoid*)bytes length:(NSUInteger)length//復制以bytes開頭、長度為length的數據,進行初始化使其成為數據對象的內容。便利構造器:dataWithBytes:length:

- (id)initWithBytesNoCopy:(void*)bytes length:(unsigned)length freeWhenDone:(BOOL)flag;//將以bytes開頭、長度為length的數據初始化為數據對象的內容。生成的NSData中保存的是指向數據的指針,并沒有對數據進行復制操作。flag為YES的時候,生成的NSData對象是bytes的所有者,當NSDate對象被釋放的時候也會同時釋放bytes,所以bytes必須是通過malloc在堆上分配的內存。當flag為NO的時候,bytes不會被自動釋放,釋放bytes時要注意時機,不要在NSData對象還被使用的時候釋放bytes。便利構造器:datawithBytesNoCopy:length:freeWhenDone:

- (id)initWithData:(NSData *)data//用指定的NSData對象aData來創建一個新的NSData對象。參數可以是NSMutableData對象,所以用這個方法可以為一個可變的NSMutableData對象生成一個不可變的NSData對象。便利構造器:dataWithData:

+ (id)data//返回一個長度為0的臨時NSDate對象。這個方法多被用于NSMutableData中(創建一個長度為0的NSData意義不大)。對應的初始化方法為init。

(2)訪問NSData中的數據

- (NSUInteger)length//返回NSData對象中數據的長度

- (

constvoid*)bytes//返回NSData對象中數據的首指針

- (

void)getBytes:(void*)buffer length:(NSUInteger)length//復制NSData對象的數據到buffer中,復制時從NSData對象中數據的開頭開始,副本的長度為length。如果想獲得指定范圍內的數據的話,可以使用方法getBytes:range:

- (NSData *)subdataWithRange:(NSRange)range

//用range指定范圍內的data來生成一個新的NSData對象并返回。

- (NSRange)rangeOfData:(NSData *)dataToFind options:(NSDataSearchOptions)mask range:(NSRange)searchRange

//在接收者中searchRange指定的范圍內,如果能找到和dataToFind一樣的數據,則返回數據的位置和長度。mask是搜索時用到的選項,使用mask可以從后向前查找。dataToFind不可以為nil。

(3)比較

- (BOOL)isEqualToData:(id)anObject//兩個NSData的數據長度和內容一致時返回YES

(4)文件輸入和輸出

可以從文件讀人數據來初始化NSData對象,或者把NSData對象中的內容輸出到文件。除了用NSString指定文件路徑的函數外,還有使用NSURL來指定文件路徑的函數。

數組類

NSArray:

數組中既可以存放同一類的對象,也可以存放不同類的對象,但不可以存放nil,nil被用于標志數組的結束。

NSArray是不可變數組,一旦創建后,就不能再添加,刪除或修改其中的元素。

數組對象的所有權:

數組,集合和詞典對象這些可以包含多個對象的容器被總稱為集合。一個對象被放入集合時會收到retain的消息,被從集合中刪除時也會收到release消息。

快速枚舉:

OC2.0提供了一個用于遍歷容器類的語法,叫做快速枚舉。for...in語法。

集合是可變的也可以是不可變的,可變集合在循環的過程中也不允許被改變,如果集合發生了改變,就會拋出異常。

遍歷容器中元素的順序和容器的類型有關。如果是數組,就會從頭開始遍歷,而如果是集合或是詞典類型,遍歷的順序則和容器的內部實現有關。

變量可以在for的條件中定義,這種情況下變量只在for...in語法塊內有效。

枚舉器NSEnumerator:

枚舉器是一個用來遍歷集合類中的元素對象的抽象類。枚舉器沒有創建實例的公有接口,不能給枚舉器發送alloc消息。使用枚舉器遍歷一個集合對象的同時,如果向該集合對象增加或刪除對象,就可能會導致不可預期的結果,是很危險的。

基于引用計數管理模式下,在通過枚舉器遍歷集合對象的時候,枚舉器對象擁有這個集合對象的所有權,取出最后一個元素之后,它就會自動放棄對這個集合對象的所有權。同時,因為枚舉器是一個臨時對象,所以當其所在的自動釋放池被釋放的時候,該枚舉器也會被釋放掉。

快速枚舉和枚舉器

快速枚舉和枚舉器在遍歷過程中,都不能改變集合中的元素。如果在遍歷過程中想要更改集合對象的話,可以使用下標來循環遍歷。如果要刪除集合中的某個元素,需要從后向前遍歷。

快速枚舉內部用c語言實現,速度快。

for...in語法可以將in后的“集合”換為“枚舉器”。

集合類:

它是一組單值對象的集合,NSSet是無序的,同一個對象只能保存一個。

NSMutableSet有一個子類NSCountedSet,是一個可變的集合類,能后統計集合中對象的個數,這個類中可以存放多個相同值的對象。

詞典類

詞典中的數據以鍵值對的形式保存,一個鍵值對稱為entry。鍵和值可以是除nil以外的任何對象,一般使用字符串作為鍵。鍵是關鍵字。

value由多個字符串構成的時候可以用()把他們括起來,這種情況下詞典對象的值就相當于一個數組對象。

詞典的鍵必須是唯一的。

詞典對象的值可以用NSNull來表明一個詞典對象為空。

一個對象作為詞典的key或者value時,詞典中存放的是這個對象的一份副本。

NSDictionary:

不可變,一旦創建就只能查詢,不可在增加,刪除,或修改其中的內容。

包裹類

Cocoa Foundation 框架的集合類中只可以放入對象,不能存儲基本類型的數據。所以Cocoa提供了NSNumber類來包裝char,int,long等基本類型的數據。像結構體,指針這類復雜的數據類型,NSNumber沒有辦法把他們存儲為對象,這時就可以使用NSValue。NSValue是NSNumber的父類,NSValue可以把任意對象包裝成對象。NSNull是為了把nil放入集合類中而定義的包裹類。

注意:NSInteger不是一個對象,而是基本的數據類型的typedef。

NSValue:

接口定義在Foundation/NSValue.h中,坐標等結構體定義在Foundation/NSGeometry.h中。

類型編碼和@encode()

OC的數據類型甚至自定義類型,都可以使用ASCII編碼的類型描述字符串來表示。@encode()可以返回給定數據類型的類型描述字符串。例如:@encode(int)返回“i”。

下面是一個為結構體創建NSValue實例的例子:

struct

grid {

int

x, y;

double

weight;

};

structgridfoo, bar;id

obj;

//對結構體foo進行封裝并返回一個對象obj的代碼

obj = [[NSValue alloc] initWithBytes:&foo objCType:

@encode(struct

grid)];

//把數據從obj中讀入到變量bar中

[obj getValue:&bar];

NSValue只能包裝長度確定的數據,例如,NSValue不能包裝一個C風格的字符串。

NSValue和NSNumber是以類簇的形式實現的,所以無法用通常的方法為其定義子類。

NSNull

nil不能放在數組或字典中,因為nil在它們中有特殊的含義,但有時我們確實需要一個特殊的對象表示空值。

NSURL

關于URL:

統一資源定位符。除用于因特網之外,也可以用于表示本機資源。除HTTP協議外,其他協議也可以使用URL來訪問資源。

Mac OS X 和iOS中規定了四種可以使用NSURL來訪問資源的形式:

http:超文本鏈接協議

https:超文本傳輸安全協議http的安全版本,是超文本傳輸協議和SSL/TLS的組合

ftp:文件傳輸協議

file:訪問某臺主機上的文件

訪問某個資源的寫法如下:

協議名://主機名/主機內資源的路徑

操作URL的時候應該使用專用的NSURL類,而不要把URL當作字符串來手工解析。

將string作為返回值的情況下,一定要經過url編碼的字符串。方法名中如果包含了string,那么世紀傳入的參數也一定是經過編碼的。另一方面,path用于表示URL的路徑,無論作為返回值還是參數都要返回為編碼的字符串。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容