0

テスト目的で次のコードを書いているだけです。

NSString *aStr = [[NSString alloc] initWithFormat:@"Foo"];
aStr = [aStr initWithFormat:@"Bar"];//Crashed here

次のエラーが表示されます。

*** initialization method -initWithFormat:locale:arguments: cannot be sent to an abstract object of class __NSCFString: Create a concrete instance!

次のコードを書くと、同じことが起こります

NSString *aStr = [NSString alloc];
aStr = [aStr initWithFormat:@"Foo"];
aStr = [aStr initWithFormat:@"Bar"]; //Crashed here

グーグルで、それがオブジェクトinitWithFormatを返すことを知りました。NSCFString私の質問は、NSCFStringの派生クラスである場合、なぜ でメソッドをNSString呼び出せないのかということです。可視性を停止できる場合、(派生クラス) のメソッドをオーバーライドせずにコードに実装するにはどうすればよいですか。initWithFormatNSCFStringNSCFString

簡単に言えば、NSCFString が NSString の派生クラスである場合、なぜその上で基本クラス (initWithFormat) メソッドを呼び出せないのでしょうか?

4

3 に答える 3

1

何が起こっているかは、[NSString initWithFormat:]メソッドがフォーマット指定子を提供していないことに気付いているためNSString、構築する必要のあるオブジェクトがないため、NSString渡した定数オブジェクトを単に返すだけだと思います ( @"Foo"):

NSString *aStr = [NSString alloc];
aStr = [aStr initWithFormat:@"Foo"];

だからaStr今のタイプNSCFStringです。これがクラッシュの原因です。

aStr = [aStr initWithFormat:@"Bar"]; //Crashed here

initただし、既存のオブジェクトでメソッドを呼び出してはいけません。したがって、クラッシュを修正するには、次のように使用します。

aStr = [[NSString alloc] initWithFormat:@"Bar"];

次のようにフォーマット指定子を使用します。

aStr = @"Foo";
aStr = @"Boo";

これは同じことですが、より明確になり、使用するコードが少なくなり、パフォーマンスが向上します。

于 2014-10-28T11:08:40.807 に答える
0

あなたは「なぜ」と尋ねています。あなたが無視した「同じオブジェクトでinitを2回呼び出すのはbaaaadです」という答えに加えて、NSStringはクラスクラスターです。

[NSString alloc] は、実際には文字列として使用できない一般的なオブジェクトを返しますが、init メソッドが呼び出されることを期待しています。明らかなことを考えてみましょう: NSString オブジェクトは不変ですが、 [NSString alloc] の結果は不変にはなりません。

その init メソッドは、実際にはinit メソッドを受け入れない別のオブジェクトを返します。[NSString alloc] は何でもできる非常に柔軟なオブジェクトですが、init メソッドを呼び出すと、二度と変更できない文字列を含むオブジェクトが返されます。

(Apple は、私が言っていることとは異なる実装を行っているか、実装を変更している可能性があります。それでも、Apple は、ユーザーが愚かなことをするのを止めることができますし、そうするでしょう)。

そして警告: NSString のサブクラス化について考えることさえしないでください。うまくいくものは何もないことを保証できます。

于 2014-10-28T11:23:31.227 に答える