NSMutableString *newPath = [NSMutableString stringWithCapacity:42];
また
NSMutableString *newPath = [[NSMutableString alloc] init];
どちらか一方を使用する必要がある特定の理由はありますか?
はい。特別な理由がない限り、常にすぐに自動解放してください。
release
最初の理由は、メッセージを書くのを非常に忘れやすいからです。オブジェクトを作成したのとまったく同じステートメントで ( のように) オブジェクトを自動解放すると[[[… alloc] init] autorelease]
、それを忘れるのがはるかに難しくなり、忘れたときに明らかになります。便利なファクトリ メソッド ( などstringWithCapacity:
) がオブジェクトを自動解放するので、自分で自動解放する場合と同様に、後で解放することを心配する必要はありません。
第二に、別のメッセージを書くことを覚えていても、release
ヒットしないのは簡単です. 早期返品には 2 つの方法があります。
NSString *str = [[NSString alloc] initWithString:@"foo"];
BOOL success = [str writeToFile:path atomically:NO];
if (!success)
return;
[str release];
およびスローまたは伝播された例外:
NSString *str = [[NSString alloc] initWithString:@"foo"];
//Throws NSRangeException if str is not in the array or is only in the array as the last object
NSString *otherStr = [myArray objectAtIndex:[myArray indexOfObject:str] + 1];
[str release];
「そうしない具体的な理由」は、通常、多くのオブジェクトを作成するタイトなループがあるためです。この場合、オブジェクト数を維持するために、ループ内のできるだけ多くのオブジェクトを手動で管理することをお勧めします。下。ただし、これが問題であるという証拠がある場合にのみ、これを行ってください(Shark からのハード ナンバー、Instruments からのハード ナンバー、またはそのループが十分に長く実行されるたびにシステムがページング地獄に陥っている場合)。
他の、おそらくより良い解決策には、ループを 2 つのネストされたループ (内側のループの自動解放プールを作成および排出するための外側のループ) に分割し、NSOperation に切り替えることが含まれます。(ただし、キューが一度に実行する操作の数に制限を必ず設定してください。そうしないと、ページング地獄に陥りやすくなる可能性があります。)
また、コンパイラにサイズ感を与えるため、最初の方が優れていますか?
その方が良いですが、その理由ではありません。
コンパイラにとっては、これは単なる別のクラス メッセージです。コンパイラは、自分が何をするかを知りませんし、気にもしません。それが知っていて気にかけているのstringWithCapacity:
は、ユーザーに曲を再生するメッセージだけです。
NSMutableStringにサイズのヒントが与えられます。クラスは、最初に割り当てたい文字ストレージの量を認識します。これによって得られるメリットはおそらく小さいものですが (少なくとも Mac では)、情報が手元にある場合は、それを使用してみませんか? 逆に、私はそれを計算するためにわざわざ行くつもりはありません。
宣言が 2 行で書かれているのをよく見かけます (つまり)。
NSMutableString *newPath;
newPath = [NSMutableString stringWithCapacity:42];
個人的にはワンライナーの方が好きですが、これは単なる個人的なスタイルの例ですか?
はい。ただし、変数を初期化しないままにしておくと、ある程度のリスクがあります。これを習慣化する場合は、必ず「Run Static Analyzer」ビルド設定をオンにしてください。