objective-c:不允许双重指向属性?

Z S*_*Z S 20 cocoa objective-c

我想创建一个这样的方法:

- (void) checkAndUpdateStringProperty: (NSString **) property{
   if (...) 
      *property = @"whatever";
}
Run Code Online (Sandbox Code Playgroud)

我想用它来传递同一个类的属性:

- (void) somewhereElse{
       ....
       [self checkAndUpdateStringProperty: &self.productName];
}
Run Code Online (Sandbox Code Playgroud)

但这会产生语法错误,说"请求的属性表达式的地址".有什么理由吗?如果我用局部变量替换class属性,它可以正常工作:

- (void) somewhereElse{
       NSString *name = nil;
       [self checkAndUpdateStringProperty: &name];
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*eld 27

只能通过getter和setter方法访问属性,除了在对象initdealloc方法中初始化和取消初始化它们(当对象不处于完全一致的状态时) - 以任何其他方式访问它们都会失败它们的目的并且不尊重它们的属性(retain,copy等).

它不编译的原因是因为属性访问器是方法调用的语法糖,并且您不能获取方法的返回值的地址.self.productName是完全相同的[self productName],&[self productName]没有任何意义.

如果你真的想这样做,不要用属性来做,只用常规变量(比如局部变量或ivar)来做,并记录你的函数的语义:调用函数是否需要release返回宾语?等等.例如,各种Apple方法NSError**指定返回的错误对象(如果有的话)是一个自动释放的对象,所以你不release应该自己,除非你也retain.

  • 谢谢.实际上想通了(因为这是一个NSManagedObject)我可以传入属性的名称并使用valueForKey访问该值,并使用setValue在'check'方法中设置它:forKey:不需要做双指针间接. (2认同)

zap*_*aph 7

Apple API中很少有以这种方式传递值的地方,主要是NSError.最好只返回结果.如果你有一个参考参数,那么一般的Apple规则就是它应该是方法名称以" get" 开头的最后一个参数getCheckAndUpdateStringProperty.

但你可以做到,这不是我们习以为常的.

您看到的错误是self.productName方法调用的真正简写:[self productName]因此 &self.productName被解释为&[self productName].

此外,在这种情况下,如果productName是具有retain属性的@property,则将颠覆引用计数.


ver*_*rec 5

如果您对所有权属性非常小心,可以通过以下方式解决此问题:

[self property]
Run Code Online (Sandbox Code Playgroud)

VS:

self.property
Run Code Online (Sandbox Code Playgroud)

VS:

self->property
Run Code Online (Sandbox Code Playgroud)

一旦你清楚了解差异,你可以试试这个:

[self checkAndUpdateStringProperty: &self->productName]
Run Code Online (Sandbox Code Playgroud)

注意使用:- >

我一直在分配属性属性时使用它,当它是一个原始的非对象类型时:(float,int,...)