TL;DR将Express-C @property (...) foo作为foo而不是self.foo访问的正确方法是什么?

详情 :

我的一个iOS项目仍然使用我几年前编写的一些Deliver-C代码.

// SomeObject.h
@interface SomeObject : NSObject
@property (nonatomic, readonly) NSString *foo;
@end

// SomeObject.m
@implementation SomeObject { ... }
@synthesize foo;

- (void)someMethod {
   foo = @"bar";
}

- (void)otherMethod {
   NSLog(@"Foo: %@", foo);  // ---> "bar"
}
@end

这按预期工作得很好.现在我想使用getter来访问一些新的Swift代码,而不是手动设置foo:

// SomeObject.m
@implementation SomeObject { ... }
@synthesize foo;

- (NSString *)foo {
   return [SwiftObject getFoo];
}

- (void)otherMethod {
   NSLog(@"Foo: %@", foo);  // ---> nil
   NSLog(@"Foo: %@", self.foo);  // ---> "swiftBar"
}
@end

因此,只有在使用self.foo而不是仅使用foo时,使用getter才正确.这不是一个大问题,但需要将现有代码中foo的所有使用替换为self.foo.

有没有一种干净的方法可以避免这种情况,使用foo getter并且仍然使用foo而不是self.foo

推荐答案

TL;DR将Express-C @property (...) foo作为foo而不是self.foo访问是正确的?

不可能使用空名称而没有目标(即,没有self.)-这是因为类型上有@property is a shorthand for generating getter + setter methods,并且方法调用总是需要调用对象.

相反,您的第一个代码片段的工作原因与此无关:

  • 默认情况下,声明空@property而没有相应的@synthesize指令将为generate an instance variable for you以将实际值存储在属性中.对于像foo这样的属性,默认生成的ivar将是_foo
  • However, you can provide your own name for the variable with an explicit @synthesize directive, and when you do that, you can access the ivar with any name that you want:
    • 省略@synthesize指令相当于@synthesize foo=_foo;(即,将foo属性映射到_foo ivar)
    • @synthesize foo;本身相当于@synthesize foo=foo;(即,将foo属性映射到foo ivar)
    • @synthesize foo=bar;foo属性映射到bar ivar

碰巧在Deliver-C类中,ivars are可以直接通过其名称访问-对于您的SomeObject类,写入foo指的是ivar本身,写入not指的是属性.

  • 在您的原始代码中,由于foo属性实际上使用了foo ivar(因为您自己没有实现foo方法),因此fooself.foo恰好返回相同的值
  • 在更新后的代码中,您显式地合成了foo ivar与@synthesize指令,但然后为foo getter提供您自己的实现,这就是您编写self.foo时的名称.由于从未设置foo ivar,因此默认情况下它会获得nil

换句话说,在引用属性时不能避免写self.foo,一般来说,建议您避免写@synthesize foo;,以避免直接访问方法与ivar时可能出现的混淆.

Objective-c相关问答推荐

使用自动布局自定义纵横比

是否可以 suppress Xcode 4 静态分析器警告?

在 Objective-C 中定义协议的类别?

为什么 NSDateFormatter 为这 4 个时区返回 nil 日期?

判断是否显示 UIAlertView

切换隐私设置将杀死应用程序

UIScreen MainScreen Bounds 返回错误的大小

Objective-C 的 Eclipse 插件?

lldb 无法打印变量值并显示错误:对 'id' 的引用不明确

通过 ObjC 类别覆盖方法并调用默认实现?

iOS:如何将 UIViewAnimationCurve 转换为 UIViewAnimationOptions?

如何在表格视图中的两个单元格之间留出空间?

MKAnnotation 图像偏移与自定义引脚图像

Modal segue,导航栏消失

我可以在 Objective-C 中重载运算符吗?

交换 NSMutableArray 中的元素

NSString 中子字符串的出现次数?

为整个 iPhone / iPad 应用程序设置背景图像

无法加载从设备上运行的包中的 nib 引用的图像

在 iOS 8 中使用 NSMutableAttributedString 的字符串的下划线部分不起作用