覆盖 getter 只需要 @synthesize

Posted

技术标签:

【中文标题】覆盖 getter 只需要 @synthesize【英文标题】:override getter only needs @synthesize 【发布时间】:2013-12-11 15:07:36 【问题描述】:

我想为惰性实例化覆盖 getter 并保留默认设置器。

我需要@synthesize 吗?

为什么?

@interface Foo()
@property (strong, nonatomic) NSObject *bar;
@end

@implementation Foo
- (NSObject *)bar

    if(!_bar) _bar = [[NSObject alloc] init];
    return _bar;

@end

更新:我更改了变量和类名,因为它令人困惑。从 Deck 和 card 到 Foo 和 bar。

【问题讨论】:

你开发什么?即ios6iOS7等因为理论上我认为它来自iOS6,当使用ARC时你不需要@synthesize 忘记@synthesize iOS7.当您同时覆盖 setter 和 getter 时,您需要 @synthesize。这个例子来自斯坦福:开发 iOS7,第 2 讲 【参考方案1】:

不,如果您显式实现所有访问器方法(readwrite 属性的 getter 和 setter,readonly 属性的 getter),您只需要显式合成(以获取合成的 ivar)。您已经为此readwrite 属性编写了getter,但没有编写setter,因此仍会为您合成ivar。因此,就您的代码而言,您不需要显式地@synthesize

如果你创建了这个属性readonly,那么实现一个getter 会阻止你的ivar 被自动合成。同样,由于这是readwrite,如果您同时实现了getter 和setter,则需要您合成ivar(如果您想要的话)。

【讨论】:

+1 换句话说:如果你的代码可以编译,你就很好。如果您需要@synthesize,编译器将不允许您使用_cards ivar。【参考方案2】:

不要以这种方式使用延迟初始化。没有卡片的 Deck 是无用的,因此,每当第一次调用该 getter 时,延迟初始化只会给您带来不确定的 CPU 消耗。幸运的是,简单地创建一个可变数组没有任何成本(这也是不使用延迟初始化的原因)。

同样,出售可变集合会破坏封装。一个套牌应该包含所有逻辑,以确定它包含哪些卡片以及按什么顺序。通过出售可变集合,外部代码可以在 Deck 背后改变该顺序。

除此之外,“设置”一副牌的牌意味着什么?走这条路似乎将所有与维护 Deck 相关的逻辑推到了 Deck 类之外,提出了一个问题,即为什么甲板只不过是任何使用甲板的类中的普通旧数组。

【讨论】:

您的某些观点并不完全有效。正如您所说,性能无关紧要。可变属性的惰性吸气剂将确保它不能被取消。例如self.cards = nil; [self.cards addObject:card]; 完美运行。 @iMartin 不能“完美地工作”,除非任意丢失状态是可以的。改变状态的 getter,即使是延迟初始化,都是糟糕的设计,随着时间的推移会导致严重的问题。最好有一个 resetState 方法,它实际上按照它所说的那样做。 @iMartin 为什么要将属性公开为readwrite?这样的属性应该是readonlysetCards: 会引发编译器错误。这里的一切听起来都像是糟糕的设计。 你们把很多事情搞砸了。我没有说任何关于暴露可变集合的事情。这当然是糟糕的设计。你注意到self了吗?我说的是在类 inside 中使用该集合。在任何地方,您都可以不小心将nil 分配到那里,之后就不会发生任何突变。这是最常用的情况之一,我使用延迟初始化。它工作完美。然后是readonly 的事情。设置卡组有什么问题?很正常,为什么要在这里提? 防御“意外分配 nil”有点浪费。 “哎呀,我不小心分配了 nil 并且丢失了所有游戏状态的集合。但是,不用担心,下次我调用 getter 时,我会返回一个空游戏状态或默认顺序的游戏状态。当然,用户永远不会注意到!” 变异的 getter 是糟糕的设计,延迟初始化通常不建议使用。【参考方案3】:

在 iOS 7 中,您通常不需要合成。如果你想要一个自定义的 getter,只需定义一个。您将免费获得默认设置器。

【讨论】:

合成与iOS7无关。 @LeoNatan:据我记得,你在 ios5 中确实必须@synthesize,对吧? 它与 xcode 和 LLVM 版本有关 - 对于 Xcode 4.4 和 LLVM Compiler 4.0,不再需要 @synthesize 指令,因为它将默认提供

以上是关于覆盖 getter 只需要 @synthesize的主要内容,如果未能解决你的问题,请参考以下文章

@synthesize

19-oc@property和@synthesize

oc27--synthesize,省略getset实现

OC基础--关键字@property 和 @synthesize

@synthesize和@dynamic分别有什么作用?

Objective-C基础之@synthesize, @dynamic