2011-12-06 46 views

回答

2

是的,但它是一種迂迴的和潛在的危險

這裏就是你要做的:

NSString *veryLargeString = ...; 
NSUInteger startingIndex = ...; 
NSData *veryLargeStringData = [veryLargeString dataUsingEncoding:NSUTF8StringEncoding]; 

const void *bytes = [veryLargeStringData bytes]; 
const void *subBytes = bytes + startingIndex; 
NSUInteger subLength = [veryLargeStringData length] - startingIndex; 

NSString *substring = [[NSString alloc] initWithBytesNoCopy:subBytes length:subLength encoding:NSUTF8StringEncoding freeWhenDone:NO]; 

這是什麼做的:

  1. 它變得作爲一系列字節的非常大的字符串;我很漂亮確定這實際上並沒有複製字節,但一定要用儀器來驗證。如果您可以將此超長字符串作爲NSData開頭而不是NSString,那麼您可以更加確信沒有任何內容會被複制。
  2. 通過使用一些指針運算
  3. 圖了多少緩衝區留
  4. 創建一個新的NSString與字節的緩衝區,但告訴獲取從NSData
  5. 指數爲字節的緩衝區的實際字節的緩衝區它複製字節,並無緩衝時NSString被釋放

那麼,這是爲什麼dangero我們?基本上,如果字節緩衝區從NSStrings下面消失,Bad Things™可能發生(可能崩潰)。

但是,如果你很聰明,這將允許您創建子字符串而不復制底層字節。


狡猾思想

你可以使veryLargeString一個保留相關聯的對象上substring(即,基本上使substringveryLargeString所有者)。這將確保veryLargeString的生命至少與substring一樣長。你會是這樣做的:

static char ParentStringKey; 

objc_setAssociatedObject(substring, &ParentStringKey, veryLargeString, OBJC_ASSOCIATION_RETAIN); 

substring被釋放,這將也會自動釋放其對veryLargeString保留。

+0

非常感謝,我現在就試試。傑出的解釋還有 – Aspyn

+0

你也可以使用'NSString'的'cStringUsingEncoding:'方法來獲得'char *',然後使用''中的C庫函數或簡單的指針化處理來處理它。可以節省幾個字節的內存,因爲它不使用臨時的'NSData'對象。您仍然可以使用'initWithBytesNoCopy:'方法來處理最終的'NSString'對象。 – Macmade

+0

+1 for Bad Things(TM)...以及一個非常漂亮的解決方案。 – Till

相關問題