【发布时间】:2010-01-13 21:02:20
【问题描述】:
假设我有以下内容:
@interface MyClass : NSObject { NSString* _foobar; }
@property (nonatomic, retain) NSString* foobar;
@end
@implementation MyClass
@dynamic foobar;
- (void) setFoobar:(NSString*)fbSet; { [_foobar release]; _foobar = [fbSet retain]; }
- (NSString*) foobar; { return _foobar; }
@end
然后:
MyClass* mcInst = [[[MyClass alloc] init] autorelease];
NSLog(@"I set 'foobar' to '%@'", (mcInst.foobar = @"BAZ!"));
查看-[MyClass setFoobar:] 的返回值,可能会假设此行将打印I set 'foobar' to '',因为赋值似乎没有返回任何内容。
但是 - 谢天谢地 - 此分配按预期运行,代码打印为 I set 'foobar' to 'BAZ!'。不幸的是,这感觉像是一个矛盾,因为调用的 setter 的返回值掩盖了赋值返回分配给它的值的事实。起初我认为mcInst.foobar = @"BAZ!"; 是在进行两次调用而不是一个块:首先是 setter,然后是 getter 以收集返回值。但是,使用 NSLog 调用检测 setter 和 getter 方法证明情况并非如此。
【问题讨论】:
-
我认为不是“为什么 NSLog 工作?”,一个更好的问题(我认为您要问的问题)是“为什么 setter 返回 void,而不是(在这种情况下) NSString* ? 我还假设 mcInst.foobar = 只是 [mcInst setFoobar: ...] 的语法糖,我猜不是...
-
是的,问题是为什么编译器在你使用
NSLog(@"I set 'foobar' to '%@'", [mcInst setFoobar: @"BAZ!"]);时会抛出错误,承认该方法不返回任何内容,但允许你以其他方式执行。 -
Brian:是的,这实际上是我想问的问题,虽然我的措辞可能隐藏了那个 =)
-
Dimitris:你的例子完美地说明了我的问题。如果属性语法确实只是简单地编译为消息发送,并且该消息返回 void,那么它为什么会起作用?!
-
我从这次对话中了解到,属性语法确实不编译为
[mcInst setFoobar: @"BAZ!"]。而且我相信 e.James 的回答准确地显示了编译器的作用。感谢您提供有用的帖子。
标签: objective-c gcc compiler-construction objective-c-runtime