Objective-C的属性赋值返回指定的值?
-
20-09-2019 - |
题
说我有以下内容:
@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
呼叫证明这不是这种情况。
解决方案
<强>快速总结:强>
此处所述的快速的答案是没有矛盾的,因为表达式的结果:
(mcInst.foobar = @"BAZ!")
实际上是@"BAZ!"
,和不 mcInst.foobar
。
更多详细信息,请在下面,但它可能有助于考虑以下修改您的setFoobar
方法:
- (void) setFoobar:(NSString*)fbSet
{
[_foobar release];
_foobar = [[NSString stringWithFormat:@"HELLO_%@", fbSet] retain];
}
有了这个代码到位,foobar
属性的值被修改,当它被设置的但你的代码行仍然会显示值“BAZ!” 的。
<强>详细信息:强>
如 newacct 指出,您的NSLog代码的工作,因为你使用赋值运算符(=),它在C语言中一些非常具体的行为(其中的Objective-C是基于)
在C中,可以执行以下操作:
x = y = z = 42;
和所有的变量,x
,y
和z
的将保持值42。
在编译器处理通过使用临时变量(*)此行为。从本质上讲,会在幕后看起来是这样的:
tempVar = 42;
z = tempVar;
y = tempVar;
x = tempVar;
沿着相同的线路,则可以执行以下操作:
SomeFunction(x = 42);
这行代码将复制的42到x中的值,然后调用SomeFunction
与42.在幕后一个参数,它看起来像这样:
tempVar = 42;
x = tempVar;
SomeFunction(tempVar);
现在,在Objective-C,您的记录线的处理,如下所示:
tempVar = @"BAZ!";
[mcInst setFooBar:tempVar];
NSLog(@"I set 'foobar' to '%@'", tempVar);
(*)注意,“temporaray变量”我描述的使用是为了说明这个概念,并且实际上可能不反映了任何给定的编译器罩下实际执行。那种实现细节的可达谁写的编译器的程序员,并且每一个可以做不同的事情。最终的结果,但是,是相同的。
其他提示
有没有需要调用一个getter - 它的值被赋予的权利有在同一行。你可以把它作为扩大至[mcInst setFoobar:@"BAZ!"], @"BAZ!"
。
在C,分配是一个表达式,其评估所分配的值
这是因为C赋值运算符的工作方式。如在ANSI C标准中所描述:
“赋值运算符存储由指定对象中的一个值 左操作数。赋值表达式具有左侧的值 分配后的操作数...“
您赋值表达式是mcInst.foobar = @"BAZ!"
。这似乎是有道理的,我认为即使分配工作通过调用一个方法上mcInst行为一样与C赋值表达式的值是赋值(@"BAZ!"
)后的左操作数所以这个值被传递到NSLog的功能。
这是相同的行为,可以让你在if (self = [super init])
的风格写的初始化器。
P.S。这是一个公平的问题要问,为什么分配值到它时,会编译呼吁属性的setter和使用mcInst.foobar
的值时以后不叫吸气。我会说,它只是假设,吸气将返回刚分配到财产,因此,吸气不叫相同的值。