【问题标题】:ObjC: proper use of property and synthesize?ObjC:正确使用属性和合成?
【发布时间】:2020-05-24 17:51:40
【问题描述】:

有谁知道为什么这段代码会遇到编译错误?我正在使用 clang 在 Catalina 上编译它。我发布了一个类似的问题here,但那是我尝试在 Linux 上使用 clang 进行编译的时候。我认为 getA 和 setA 是通过综合自动生成的。谢谢!

#import <Foundation/Foundation.h>

@interface A: NSObject

@property int a;

@end

@implementation A
{
    int a;
}
@synthesize a;

@end

int main (int argc, char * argv[])
{
  @autoreleasepool {
    A *a = [[A alloc] init];

    [a setA:99];
    int v = [a getA];
    NSLog (@" %d\n", v);
  }
  return 0;
}

编译:

$ clang -framework Foundation otest0.m -o hello
otest0.m:23:16: warning: instance method '-getA' not found (return type defaults
      to 'id') [-Wobjc-method-access]
    int v = [a getA];
               ^~~~
otest0.m:3:12: note: receiver is instance of class declared here
@interface A: NSObject
           ^
otest0.m:23:9: warning: incompatible pointer to integer conversion initializing
      'int' with an expression of type 'id' [-Wint-conversion]
    int v = [a getA];
        ^   ~~~~~~~~
2 warnings generated.

【问题讨论】:

    标签: objective-c clang


    【解决方案1】:

    getter/setter 对被合成为

    -(int)a;
    -(void)setA:(int)val;
    

    所以你需要:

    int main (int argc, char * argv[])
    {
      @autoreleasepool {
        A *a = [[A alloc] init];
    
        [a setA:99];
        int v = [a a];
        NSLog (@" %d\n", v);
      }
      return 0;
    } 
    

    【讨论】:

    • 谢谢你解决了这个问题。我很困惑为什么没有将 getter 合成为 getA 以与 setA 相对应。
    • 在属性声明中有一些符号可以做到这一点,但这种形式是默认样式。
    • 感谢有道理,我很惊讶苹果没有坚持使用 setX getX,而是选择了 setX, x。
    【解决方案2】:

    声明一个名称为a 的属性会生成一个名称为a 的getter,而不是getA。 这是第一个警告的内容:“未找到实例方法'-getA'”

    【讨论】:

      【解决方案3】:

      这适用于我的系统 (macOS):

      #import <Foundation/Foundation.h>
      
      @interface A: NSObject
      
      @property int a;
      
      @end
      
      @implementation A {
        int a;
      }
      @synthesize a;
      
      -(int) getMyValue {
      return a;
      }
      
      @end
      
      int main () {
        @autoreleasepool {
          A *a = [[A alloc] init];
         [a setA:99];
         NSLog (@"value = %d", [a getMyValue]);
       }
        return 0;
      }
      
      

      如果文件保存为 synth.m,终端命令为:clang synth.m -framework Foundation -o synth && ./synth

      【讨论】:

      • 我可以确认您的代码有效。现在,不应该综合创建两个方法getA 和setA 吗?我尝试将 getMyValue 更改为 getA 并导致编译错误。你也观察到这一点吗?谢谢
      • 如果将方法更改为 -(int)getA 然后在 main 中使用 [a getA] 来检索它,它应该可以正常编译。
      • 我认为你期望每个“set”都有一个“get”,而实际上 objc 不使用“get”这个词作为 getter,只使用“set”作为 setter .
      • 我读到的每一个地方都说 synthesize 会自动创建一个 getter 和/或 setter 方法。所以你是说它只创建一个二传手?谢谢
      • 不,它会同时创建两者,但您只能将“set”用于设置器。 objc 的创建者没有使用“get”作为 getter。根据 Kochan 在《Objective-C 编程》中的说法:设置实例变量值的方法通常统称为 setter,用于检索实例变量值的方法称为 getter。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 2019-07-03
      • 2013-03-01
      • 2010-10-20
      相关资源
      最近更新 更多