2011-12-06 2 views
2

IOS ApiにはsubstringFromIndexのような機能がありますが、他の点ではメモリの使用量が非常に少ない(私は非常に大きな文字列を使用しています)。もし私がその機能を果たさなければならないなら、それをどうやってやるのだろう?substringFromIndexのようなメモリ使用量が少ない機能はありますか?

事前

+0

いいえ、存在しません。 – PengOne

+0

そのような機能を実現する方法はありますか?それをどうやってやるのでしょうか? – Aspyn

答えて

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というスーパー長い文字列を使用すると、何もコピーされないことがはるかに自信があります。
  2. バイトのバッファを持つ、新しいNSStringを作成しますが、言って、いくつかのポインタ演算に
  3. を残しているどのくらいのバッファの
  4. 図アウトを使用して、バイトバッファにNSData
  5. インデックスから実際のバイトのバッファを取得それにませは、バイトをコピーして、ませ空きバッファにNSStringは、なぜこのdangeroある
  6. ので

割り当てが解除されたとき米国?基本的に、バイトバッファがNSStringsの下から消えた場合、Bad Things™が発生する可能性があります(クラッシュする可能性があります)。

しかし、これについて賢明ならば、基礎となるバイトをコピーせずに部分文字列を作成することができます。


よこしまな考え:あなたはsubstringveryLargeString保持関連付けられたオブジェクトを作ることができる

(すなわち、基本的にsubstringveryLargeStringの所有者を作ります)。これにより、少なくともsubstringと同じくらい長くveryLargeStringが存続することが保証されます。あなたはこのようにそれを行うだろう:substringの割り当てが解除された場合

static char ParentStringKey; 

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

を、それはまた、自動的にそのveryLargeStringに保持を解除します。

+0

ありがとう、私は今それを試してみます。優れた説明 – Aspyn

+0

'NSString'の' cStringUsingEncoding: 'メソッドを使って' char * 'を取得し、それを処理するために' 'のCライブラリ関数を使うか、単にポインタarythmeticsを使うこともできます。一時的な 'NSData'オブジェクトを使用しないので、数バイトのメモリを節約することができます。最後の 'NSString'オブジェクトに' initWithBytesNoCopy: 'メソッドを使用することはできます。 – Macmade

+0

+1 Bad Things(TM)の場合は...まあ、本当に気の利いた解決策です。 – Till

関連する問題