在多次搜索和读取属性属性之后,我仍然无法完全理解它们并创建一个正确使用它们的反射。
我有多个问题:
1)default
属性是什么意思?
据我所知,未在“组”中指定属性,使用默认属性,因此:
@property NSString *string;
是atomic
,对吧?
按照这种逻辑,this article说strong
和assign
是默认值,所以如果我有:
@property (nonatomic) NSString *string;
是string
属性strong
还是assign
?
可用属性如何“分组”?或者像Xcode这样说,哪些属性是互斥的?
2)是否应该遵循一般规则?
例如,我看到一条评论说您应该将copy
用于包含NSString
,NSArray
等可变变体的类。
另一个说你应该使用assign
来表示C对象。
所以,总是使用它是个好主意:
@property (copy, nonatomic) NSString *string;
@property (assign, nonatomic) CGFloat float;
属性属性还有哪些其他标准做法?
3)如果我使用“错误”属性会出现什么问题?如果我只对项目中的所有属性使用nonatomic
该怎么办?
答案 0 :(得分:23)
1a)属性的默认属性为atomic
,strong
(对象指针)或assign
(对于基本类型)和readwrite
。这假设一个全ARC项目。
因此@property NSString *string;
与@property (atomic, strong, readwrite) NSString *string;
相同。 @property int value;
与@property (atomic, assign, readwrite) int value;
相同。
1b)属性分组如下:
从这三组中的每一组中挑选一个且仅一个。
实际上,最新的Objective-C添加了对nullable/nonnull
的支持,默认为nullable
。
2)一般规则如你所说。
strong
。assign
。weak
以避免引用周期。通常,父母对其子女有强烈的引用,而子女对其父母的引用较弱。由于同样的原因,代表通常是weak
。copy
通常用于NSString
,NSArray
,NSDictionary
等,以避免在分配可变变体时出现问题。这避免了意外更改值的问题。copy
与NSMutableString
,NSMutableArray
等一起使用,因为当您将可变值分配给属性时,copy
属性会导致调用copy
方法它返回原始值的不可变副本。解决方案是覆盖setter
方法以调用mutableCopy
。3)根据属性的需要和使用的属性,使用错误的属性可能会出现严重问题。
使用assign
代替strong
作为对象指针可能是最糟糕的错误。由于尝试访问已解除分配的对象,它可能导致应用程序崩溃。
在多个线程上同时访问的属性上使用nonatomic
而不是atomic
可能会导致很难发现错误和/或崩溃。
对strong
或copy
(以及其他集合)使用NSString
代替NSArray
可能会导致细微且难以找到错误,如果可变变体是分配给属性和其他代码稍后修改这些值。
答案 1 :(得分:1)
@rmaddy的答案很好。
我要添加以下内容。
如果您正在创建(或继承)与Swift互操作的类,则包含nullable
或nonnull
属性属性非常很有用。如果将其添加到头文件的任何部分,则需要为头文件的所有部分指定它(编译器警告会为您提供帮助)。对于Objective-C调用者来说,从方法签名中知道什么可能是 nil 值,甚至可能不是很有用。
另一个值得注意的属性是class
。您可以可以向类添加属性。
将这两项合并在一起,如果要实现单例,则
+ (MyClass *)sharedInstance;
将其定义为属性非常有用:
@property (class, nonatomic, nonnull, readonly) MyClass *sharedInstance;
(在这种情况下,您需要按照in this article的说明为其添加后备变量)
这将使您可以通过点表示法访问共享实例。
[MyClass.sharedInstance showMeTheMoney:YES];
在Swift中,这很烦人
MyClass.sharedInstance()?.showMeTheMoney(true)
变成
MyClass.sharedInstance.showMeTheMoney(true)
‡也许对您来说只有3个字符,但这可以防止我在中午爆炸。