Objective-C:将属性引用传递给方法调用的正确方法

ike*_*8me 3 macos cocoa objective-c ios

如果我有这样的属性:

@property(strong, readwrite, nonatomic) NSDate* aProperty;
Run Code Online (Sandbox Code Playgroud)

我想将引用传递给另一个方法,这些是正确的:

if([AnotherClass aMethod:&(self.aProperty)]) { ...
if([AnotherClass aMethod:&self.aProperty]) { ...
Run Code Online (Sandbox Code Playgroud)

Rem*_*rrr 10

您可以使用KeyValue编码.

只需将属性的名称作为NSString发送

- (void) method:(NSString*)propertyName
{
  [self setValue:[NSNumber numberWithInt:2] forKey:propertyName];
}
Run Code Online (Sandbox Code Playgroud)

一个属性也只是方法(set和get),所以你可以传递一个选择器

SEL selector = @selector(setProperty:);

- (void) method:(SEL)selector target:(id)target
{
  [target performSelector:selector withObject:[NSNumber numberWithInt:2]];
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用键值编码.


Rob*_*Rob 10

考虑你的例子:

if ([AnotherClass aMethod:&(self.aProperty)]) { ...
Run Code Online (Sandbox Code Playgroud)

这显然不起作用,因为点符号实际上是使用getter访问器方法.它相当于:

if ([AnotherClass aMethod:&[self aProperty]]) { ...
Run Code Online (Sandbox Code Playgroud)

你可以很容易地想象为什么编译器对这种表示法有点困惑.合乎逻辑的选择是参考ivar.因此,(假设您正在使用属性的ivar的下划线约定),它可能看起来像:

if ([AnotherClass aMethod:&_aProperty]) { ...
Run Code Online (Sandbox Code Playgroud)

但是,有各种各样的问题(绕过二传手,具有约问题aMethod需要__strong属性来替代默认__autoreleasing为讨论在这里,等).

所以,最好的,只需要一个接收更新的局部变量,然后在之后调用属性的setter:

NSDate *date;
if ([AnotherClass aMethod:&date]) { ...

self.aProperty = date;
Run Code Online (Sandbox Code Playgroud)