Objective-C属性属于最佳实践

时间:2016-02-04 10:46:14

标签: objective-c properties

在多次搜索和读取属性属性之后,我仍然无法完全理解它们并创建一个正确使用它们的反射。

我有多个问题:

1)default属性是什么意思?

据我所知,未在“组”中指定属性,使用默认属性,因此:

@property NSString *string;

atomic,对吧?

按照这种逻辑,this articlestrongassign是默认值,所以如果我有:

@property (nonatomic) NSString *string;

string属性strong还是assign

可用属性如何“分组”?或者像Xcode这样说,哪些属性是互斥的?

2)是否应该遵循一般规则?

例如,我看到一条评论说您应该将copy用于包含NSStringNSArray等可变变体的类。

另一个说你应该使用assign来表示C对象。

所以,总是使用它是个好主意:

@property (copy, nonatomic) NSString *string;
@property (assign, nonatomic) CGFloat float;

属性属性还有哪些其他标准做法?

3)如果我使用“错误”属性会出现什么问题?如果我只对项目中的所有属性使用nonatomic该怎么办?

2 个答案:

答案 0 :(得分:23)

1a)属性的默认属性为atomicstrong(对象指针)或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通常用于NSStringNSArrayNSDictionary等,以避免在分配可变变体时出现问题。这避免了意外更改值的问题。
  • 有一个很大的"陷阱"将copyNSMutableStringNSMutableArray等一起使用,因为当您将可变值分配给属性时,copy属性会导致调用copy方法它返回原始值的不可变副本。解决方案是覆盖setter方法以调用mutableCopy

3)根据属性的需要和使用的属性,使用错误的属性可能会出现严重问题。

  • 使用assign代替strong作为对象指针可能是最糟糕的错误。由于尝试访问已解除分配的对象,它可能导致应用程序崩溃。

  • 在多个线程上同时访问的属性上使用nonatomic而不是atomic可能会导致很难发现错误和/或崩溃。

  • strongcopy(以及其他集合)使用NSString代替NSArray可能会导致细微且难以找到错误,如果可变变体是分配给属性和其他代码稍后修改这些值。

答案 1 :(得分:1)

@rmaddy的答案很好。

我要添加以下内容。

如果您正在创建(或继承)与Swift互操作的类,则包含nullablenonnull属性属性非常很有用。如果将其添加到头文件的任何部分,则需要为头文件的所有部分指定它(编译器警告会为您提供帮助)。对于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个字符,但这可以防止我在中午爆炸。