私の理解が正しければ、Objective-C では、プロパティは getter と setter で自動的に合成され、インスタンス変数はプロパティ名として宣言され、アンダースコアが先頭に追加されます ( _ivar
)。
したがって、このコード:
main.m
#import <Foundation/Foundation.h>
#import "hello.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
Hello *hello = [[Hello alloc] init];
NSLog(@"%@", hello.myString);
return 0;
}
}
こんにちは。
#import <Foundation/Foundation.h>
@interface Hello : NSObject
@property (copy, nonatomic) NSString *myString;
@end
こんにちは。
#import "hello.h"
@implementation Hello
-(Hello *)init
{
if (self = [super init]) {
_myString = @"Hello";
}
return self;
}
-(NSString *)myString
{
return [NSString stringWithFormat:@"%@ %@", _myString, @"World"];
}
@end
次のようにコンパイルして実行できます。
bash-3.2$ clang -framework Foundation main.m hello.m -o hello
bash-3.2$ ./hello
2013-05-27 13:20:39.738 hello[23320:707] Hello World
myString プロパティを readonly に変更すると、次のようになります。
@property (readonly, copy, nonatomic) NSString *myString;
次に、コンパイルしようとすると、エラーが発生します。
hello.m:11:9: error: unknown type name '_myString'; did you mean 'NSString'?
_myString = @"Hello";
^~~~~~~~~
NSString
だから_myString
定義されていません。コンパイラは、インスタンス変数 _myString を使用してプロパティを合成しませんでしたか? 自分で合成したときに機能するかどうかを見てみましょう。
hello.m の実装では:
@synthesize myString = _myString;
これで再び動作します:
bash-3.2$ clang -framework Foundation main.m hello.m -o hello
bash-3.2$ ./hello
2013-05-27 13:36:59.916 hello[24219:707] Hello World
readonly
だから、私の質問は、プロパティで使用するときにアンダースコアivarで自動的に合成されないのはなぜですか? それとも、このObjective-Cの仕組みを理解するのに完全に間違った道を進んでいますか?
正確に何が起こっているのか、その理由を本当に理解したいので、説明的な答えをいただければ幸いです。
前もって感謝します。