override getter only needs @synthesize

2019-04-26 10:15发布

问题:

I want to ovveride getter for lazy instantiation and leave default setter.

Do I need @synthesize ?

Why ?

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

@implementation Foo
- (NSObject *)bar
{
    if(!_bar) _bar = [[NSObject alloc] init];
    return _bar;
}
@end

Update: I've changed variable and class name, because it was confusing. From Deck and card to Foo and bar.

回答1:

No, you only need to explicitly synthesize (to get the synthesized ivar) if you explicitly implement all of the accessor methods (both getter and setter for readwrite properties, just the getter for readonly properties). You've written the getter for this readwrite property, but not the setter, so the ivar will still be synthesized for you. Thus, as your code stands, you do not need to explicitly @synthesize.

If you made this property readonly, then implementing a getter would prevent your ivar from being automatically synthesized. Likewise, since this is readwrite, if you implemented both the getter and the setter, that would require you to synthesize the ivar (if you wanted one).



回答2:

Don't use lazy initialization this way. A Deck is useless without cards and, thus, lazy initialization buys you nothing but an indeterminate consumption of CPU whenever the first call to that getter might be. Fortunately, simply creating a mutable array costs nothing (which is also a reason not to use lazy initialization).

As well, vending a mutable collection breaks encapsulation. A Deck should contain all the logic for determine what set of Cards it contains and in what order. By vending a mutable collection, an external bit of code can change that order behind the Deck's back.

Beyond that, what does it even mean to "set" a Deck's cards? Going that route seemingly pushes all logic related to maintaining the Deck outside of the Deck class, begging the question as to why the deck is nothing more than a plain old array in whatever class uses the deck.



回答3:

In iOS 7, you don't normally need synthesize. If you want a custom getter, just define one. You'll get the default setter for free.