你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> NSString學習

NSString學習

編輯:IOS技巧綜合
[摘要]本文是對NSString學習的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。
基本概念

  • NSString是以UTF-16 code uint的序列。所有的長度、字符、范圍都是以16比特platform-endian(大端序小段序基於平台)的形式表示的。
    所以,一個英文字母的長度是1,一個漢字的長度也是1,而emoji表情的長度可能是2,3,4等等。 NSString可以從c緩沖區、NSdata對象以及NSUrl的內容中生成,也可以轉化為這些內容。可以在ASCII、UTF-8、UTF-16、UTF-32以及其他編碼格式之間轉換。
關於字符
  • NSString的兩個基本方法是- (unichar)characterAtIndex:(NSUInteger)index@property(readonly) NSUInteger length。 對於字符串的比較、查找等等都是以字符為基礎的。也就是說比較時,是挨個字符(character)比較的。 unichar是UTF-16編碼單位。typealias unichar = UInt16
解析UTF-16數據
當解析UTF-16數據(也就是比特數組按照UTF-16的格式解析),如果沒有BOM(byte-order mark)指定端序,那麼默認是大端序。
子類、object composition與category
  • 實現NSString的子類,需要實現NSString的backing store(可以是靜態數組、動態分配的數組或者其他的數據形式)、length方法與charAtIndex方法。 另一個選擇是聲明一個類,將NSString作為一個屬性,並將需要的其它的metadata也作為屬性存儲在類中。並實現需要用到的NSString的方法(其實就是調用這個類NSString屬性的方法)及其他方法。 category。 對所有的NSString對象都會起作用,有時會有導致意想不到的效果。不過可以增加NSString的功能。
生成NSString的方法
  • 從比特數組中生成
    - (instancetype)initWithBytes:(const void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding;
    從指定長度的比特數組中以指定的編碼格式解析得到NSString。當len比比特數組的長度還長時,返回nil。 從unichar數組中生成。
    - (instancetype)initWithCharacters:(const unichar *)characters length:(NSUInteger)length; 從C字符串中的生成
    - (instancetype)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
    由於C字符串是以NULL終結的,所以字符串中不能有NULL。所以編碼格式只能是8比特為基礎的,因為比8比特寬的字符格式(比如UTF-16),一個編碼單位可能有NULL比特。 從參數創建
    - (instancetype)initWithFormat:(NSString *)format locale:(id)locale arguments:(va_list)argList; 從NSData創建
    - (instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
    data中,按照encoding解析,得到UTF-16的code unit序列。 從文件中創建
    • 以指定編碼格式創建
      - (instancetype)initWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError * _Nullable *)error;
      如果文件打不開或者編碼錯誤,返回nil。 從文件中創建,並返回解析用的編碼格式 - (instancetype)initWithContentsOfFile:(NSString *)path usedEncoding:(NSStringEncoding *)enc error:(NSError * _Nullable *)error;
      編碼格式以指針方式返回。
  • 從URL中創建
    • 以指定編碼格式創建
      - (instancetype)initWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError * _Nullable *)error; 返回解析用的編碼格式
      - (instancetype)initWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc error:(NSError * _Nullable *)error;

寫到文件或URL中

  • 寫到文件中
    - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError * _Nullable *)error;
    如果useAuxiliaryFileYES,那麼會生成一個臨時的文件,把String寫到這個文件中,然後將這個文件重命名為目標文件。這保證了及時系統crash,也不會導致已存在的文件(如果存在)會損壞。
    這個方法把編碼信息存儲在文件的擴展屬性中,名字是com.apple.TextEncodin,值是編碼的IANA名字+分號+編碼格式的CFStringEncoding值。從文件裡生成字符串時,也是用這些個信息來決定編碼格式的。例如
    • MACINTOSH;0 UTF-8;134217984 UTF-8; ;3071
dd = @"d";
NSString *file = [NSHomeDirectory() stringByAppendingPathComponent:@"test"];
NSError *error = nil;
[dd writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (nil == error)
{
    NSLog(@"write success");
}

NSDictionary *attrbuteDict = [[NSFileManager defaultManager] attributesOfItemAtPath:file error:&error];
NSDictionary *extendAtt = [attrbuteDict objectForKey:@"NSFileExtendedAttributes"];

NSData *attrData = [extendAtt objectForKey:@"com.apple.TextEncoding"];
NSString *attrStr = [[NSString alloc] initWithData:attrData encoding:NSUTF8StringEncoding];


- 寫到URL中去

- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError * _Nullable *)error;

獲取長度

  • 獲取UTF-16 code unit長度
    @property(readonly) NSUInteger length。不是打印出來字符的長度。 使用某種編碼格式編碼,比特數組的長度。
    - (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)enc; 時間復雜度O(n) d 使用某種格式編碼,比特數組的不精確上界。
    - (NSUInteger)maximumLengthOfBytesUsingEncoding:(NSStringEncoding)enc;。時間復雜度O(1).

獲取UTF-16編碼單位的數組

  • - (void)getCharacters:(unichar *)buffer range:(NSRange)range;
    buffer必須足夠大。 - (BOOL)getBytes:(void *)buffer maxLength:(NSUInteger)maxBufferCount usedLength:(NSUInteger *)usedBufferCount encoding:(NSStringEncoding)encoding options:(NSStringEncodingConversionOptions)options range:(NSRange)range remainingRange:(NSRangePointer)leftover;
    這個方法不會crash。

獲取C字符串(以NULL結尾的字符串)
調用之前先使用- (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding;方法確定是否可以無失真的編碼。

這些方法都不要調用UTF-16,UTF-32編碼格式,因為這些包括NULL字節。

  • - (const char *)cStringUsingEncoding:(NSStringEncoding)encoding;
    這個字符串會在調用者被dealloc之前有效,delloc之後無效。
    - (BOOL)getCString:(char *)buffer maxLength:(NSUInteger)maxBufferCount encoding:(NSStringEncoding)encoding;
    buffer需要自己分配內存,因此生命周期自己控制。

字符串的比較

  • - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare locale:(id)locale;
    比較字符串時的選項
    • NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch NSAnchoredSearch NSNumericSearch NSDiacriticInsensitiveSearch NSWidthInsensitiveSearch NSForcedOrderingSearch NSRegularExpressionSearch
  • 前綴後綴
    • - (BOOL)hasSuffix:(NSString *)str; - (BOOL)hasSuffix:(NSString *)str;
    是否相同
    - (BOOL)isEqualToString:(NSString *)aString;
    這個方法比isEqual:方法要快一些。

組合字符串

  • stringByAppendingFormat: - (NSString *)stringByPaddingToLength:(NSUInteger)newLength withString:(NSString *)padString startingAtIndex:(NSUInteger)padIndex;
    padStringpadIndex開始填充。
    • [@"abc" stringByPaddingToLength: 9 withString: @"." startingAtIndex:0]; // Results in "abc......" [@"abc" stringByPaddingToLength: 2 withString: @"." startingAtIndex:0]; // Results in "ab" [@"abc" stringByPaddingToLength: 9 withString: @". " startingAtIndex:1]; // Results in "abc . . ."
      // Notice that the first character in the padding is " "。因為@". "的charAtIndex:1是" "。

分隔字符串

  • 根據分隔符生成數組。
    • - (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator; - (NSArray<NSString *> *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator;
  • 去掉字符串前後的指定字符
    • - (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set;
    取字符串的一部分
    - (NSString *)substring***類的方法

查找字符串

  • 字符查找
    - (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)searchSet options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch; 字符串查找
    - (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch locale:(NSLocale *)locale; 按行枚舉
    - (void)enumerateLinesUsingBlock:(void (^)(NSString *line, BOOL *stop))block; 按照NSStringEnumerationOptions枚舉
    - (void)enumerateSubstringsInRange:(NSRange)range options:(NSStringEnumerationOptions)opts usingBlock:(void (^)(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop))block;
    常見的NSStringEnumerationOptions
    • NSStringEnumerationByLines NSStringEnumerationByParagraphs(段落分隔符是什麼) NSStringEnumerationByComposedCharacterSequences 一個emoji表情包括若干UTF6 code unit,這個可以按照emoji表情來枚舉。  NSStringEnumerationByWords NSStringEnumerationBySentences NSStringEnumerationReverse(反向) NSStringEnumerationSubstringNotRequired(不會有substring傳入到block中,出於性能考慮) NSStringEnumerationLocalized

字符串替換

  • `- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange;

分行和分頁

  • 分行符
    • U+000A Unicode Character 'LINE FEED (LF)' (\n) U+000D Unicode Character 'CARRIAGE RETURN (CR)' (\r) U+0085 Unicode Character 'NEXT LINE (NEL)' U+2028 Unicode Character 'LINE SEPARATOR' U+2029 Unicode Character 'PARAGRAPH SEPARATOR'\r\n, in that order (also known as CRLF)
  • 分段符
    • ?????

ComposedCharacter

我理解就是由多個UTF16 code unit表示的字符。為了避免被截斷,需要確定包含指定index的完整的ComposedCharacter。
- (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;

確定String在屏幕上的大小

- (CGSize)sizeWithAttributes:(NSDictionary<NSString *,id> *)attrs;

這個函數返回的包括小數,因此需要對返回值調用ceil函數。

stringByFoldingWithOptions:locale????

找到共同的前綴

- (NSString *)commonPrefixWithString:(NSString *)str options:(NSStringCompareOptions)mask;

編碼相關

  • 是否可以以某種形式無失真編碼
    - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding; 根據NSData來探測這個NSData的編碼格式
    + (NSStringEncoding)stringEncodingForData:(NSData *)data encodingOptions:(NSDictionary<NSStringEncodingDetectionOptionsKey,id> *)opts convertedString:(NSString * _Nullable *)string usedLossyConversion:(BOOL *)usedLossyConversion;
    探測編碼格式時的選項String Encoding Detection Options
    • suggestedEncodingsKey
      建議探測的編碼格式。是NSSNumebr的數組。會優先考慮這些編碼格式。 disallowedEncodingsKey
      不允許的編碼格式。是NSNumber的數組。 useOnlySuggestedEncodingsKey
      是否只允許探測建議的編碼格式。 allowLossyKey
      是否允許失真解碼。 fromWindowsKey
      是否考慮Windows編碼格式 lossySubstitutionKey
      失真解碼下,不支持的字符被什麼替代。是一個NSString對象,默認是U+FFFD。 likelyLanguageKey
      NSdata可能來來源語言。two-letter ISO 639-1 language code,NSString對象。
  • 轉化為NSData
    - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)lossy; 無失真編碼下的最快編碼格式
    @property(readonly) NSStringEncoding fastestEncoding; 無失真編碼格式下占用空間最小的格式
    @property(readonly) NSStringEncoding smallestEncoding

URL相關

  • URL編碼
    - (NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters;
    去除URL編碼
    @property(readonly, copy) NSString *stringByRemovingPercentEncoding;

文件路徑相關

  • 把字符串用路徑分隔符連接起來
    class func path(withComponents components: [String]) -> String 把路徑用分隔符分隔,得到數組
    var pathComponents: [String] { get }

    把路徑表示成系統形式的c字符串

    @property(readonly) const char *fileSystemRepresentation;

    char filenameBuffer[13];
    BOOL success;
    success = [@"/mach_kernel"  getFileSystemRepresentation:filenameBuffer maxLength:12];
    // success == NO
    // Changing the length to include the NULL character does work
    success = [@"/mach_kernel" getFileSystemRepresentation:filenameBuffer maxLength:13];
    // success == YES
    

    獲取最後一個路徑名字

    @property(readonly, copy) NSString *lastPathComponent;

    路徑擴展名

    @property(readonly, copy) NSString *pathExtension;

    處理~

    • ~擴展為絕對路徑
      @property(readonly, copy) NSString*stringByExpandingTildeInPath; 絕對路徑縮寫~
      @property(readonly, copy) NSString *stringByAbbreviatingWithTildeInPath;
  • 在路徑名後加子路徑

    - (NSString *)stringByAppendingPathComponent:(NSString *)str;

    路徑後加後綴

    - (NSString *)stringByAppendingPathExtension:(NSString *)str;

    刪除最後一段路徑

    @property(readonly, copy) NSString *stringByDeletingLastPathComponent;

    刪除路徑後綴

    @property(readonly, copy) NSString *stringByDeletingPathExtension;

    解析符號鏈接(快捷方式)

    @property(readonly, copy) NSString *stringByResolvingSymlinksInPath;

    標准化路徑

    @property(readonly, copy) NSString *stringByStandardizingPath;

    • 擴展~號為絕對路徑 如果可以,移除起始的“/private/var/automount”, “/var/automount”“/private”。 處理///./ 移除最後一個路徑段的尾斜線 處理符號鏈接如../

更多知識

  • 字符編碼筆記:ASCII,Unicode和UTF-8
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved