`nonatomic` 在声明为 属性(包括 class 属性)的 `readonly` 中有意义吗?
Does `nonatomic` makes sense in a `readonly` declared property (including class property)?
编辑:这个问题也适用于普通声明的属性(不仅适用于 class 属性)!
原文Post:
假设我有 public class 方法 sharedInstance
目前作为 getter 方法实现:
@interface MyClass
+ (instancetype)sharedInstance;
- (void)doSomething;
@end
@implementation MyClass
+ (instancetype)sharedInstance {
static MyClass *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[MyClass alloc] init];
});
return shared;
}
@end
在 Swift 3.0 中访问此方法将如下所示:MyClass.shared().doSomething()
所以为了让它更 迅速 我们应该将 class 方法更改为 class 属性([=37= 中的新方法) ] 8.但实际上我在Apple Docu中找不到它,只能在WWDC 2016视频中找到)
@interface MyClass
@property (class, nonatomic, readonly) MyClass *sharedInstance;
- (void)doSomething;
@end
// implementation stays the same
现在 Swift 代码:MyClass.shared.doSomething()
nonatomic/atomic
属性 修饰符(不知道确切的术语)对于我在 objc 中自己实现的 getter 方法也有意义吗?
出于多种原因,atomic
/nonatomic
修饰符对您的情况无效。
主要原因是原子性关键字只影响生成的代码(即合成访问器方法)。当您在接口中声明一个 @property
,然后在您的实现中使用一个方法(或方法对)实现它时,编译器不会生成代码,因此您的原子性关键字将被忽略。
有几种方法可以解决这种情况,而您正在触发其中的几种方法:
首先,你有一个class
属性。编译器无法为 class 属性合成访问器或存储——这意味着没有代码生成,因此原子性不适用。
其次,在 readonly
属性的最常见用途中,@property
声明由手动实现的 getter 方法支持——这意味着没有代码生成因此原子性不适用。
(请注意,您还可以在 public 接口中将实例属性声明为 readonly
,并由于实现中的私有 readwrite
重新声明而合成。在在这种情况下,不仅原子性适用,您还必须使原子性关键字在您的 public 和私有声明之间匹配。您也可以仅合成一个 getter 并在您的实现中直接使用支持 ivar。 )
因为为此 属性 指定 atomic
或 nonatomic
都不起作用,所以您可以自由地将原子性关键字完全排除在声明之外。 (编译器将假定 atomic
,但如前所述,该假定无效。)
这很有道理。 属性 的 声明 为 class 的用户提供了信息。 class 的用户可以期望从合成的或手动的实现中得到您在声明中所说的内容。合成与否用户都不知道
如果您自己实现 getter(或任何访问器),您应该在 属性 的声明中反映您实现的原子性。如果您有非原子实现,则应将其添加到声明的 属性.
编辑:这个问题也适用于普通声明的属性(不仅适用于 class 属性)!
原文Post:
假设我有 public class 方法 sharedInstance
目前作为 getter 方法实现:
@interface MyClass
+ (instancetype)sharedInstance;
- (void)doSomething;
@end
@implementation MyClass
+ (instancetype)sharedInstance {
static MyClass *shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[MyClass alloc] init];
});
return shared;
}
@end
在 Swift 3.0 中访问此方法将如下所示:MyClass.shared().doSomething()
所以为了让它更 迅速 我们应该将 class 方法更改为 class 属性([=37= 中的新方法) ] 8.但实际上我在Apple Docu中找不到它,只能在WWDC 2016视频中找到)
@interface MyClass
@property (class, nonatomic, readonly) MyClass *sharedInstance;
- (void)doSomething;
@end
// implementation stays the same
现在 Swift 代码:MyClass.shared.doSomething()
nonatomic/atomic
属性 修饰符(不知道确切的术语)对于我在 objc 中自己实现的 getter 方法也有意义吗?
出于多种原因,atomic
/nonatomic
修饰符对您的情况无效。
主要原因是原子性关键字只影响生成的代码(即合成访问器方法)。当您在接口中声明一个 @property
,然后在您的实现中使用一个方法(或方法对)实现它时,编译器不会生成代码,因此您的原子性关键字将被忽略。
有几种方法可以解决这种情况,而您正在触发其中的几种方法:
首先,你有一个
class
属性。编译器无法为 class 属性合成访问器或存储——这意味着没有代码生成,因此原子性不适用。其次,在
readonly
属性的最常见用途中,@property
声明由手动实现的 getter 方法支持——这意味着没有代码生成因此原子性不适用。(请注意,您还可以在 public 接口中将实例属性声明为
readonly
,并由于实现中的私有readwrite
重新声明而合成。在在这种情况下,不仅原子性适用,您还必须使原子性关键字在您的 public 和私有声明之间匹配。您也可以仅合成一个 getter 并在您的实现中直接使用支持 ivar。 )
因为为此 属性 指定 atomic
或 nonatomic
都不起作用,所以您可以自由地将原子性关键字完全排除在声明之外。 (编译器将假定 atomic
,但如前所述,该假定无效。)
这很有道理。 属性 的 声明 为 class 的用户提供了信息。 class 的用户可以期望从合成的或手动的实现中得到您在声明中所说的内容。合成与否用户都不知道
如果您自己实现 getter(或任何访问器),您应该在 属性 的声明中反映您实现的原子性。如果您有非原子实现,则应将其添加到声明的 属性.