Questions about a readonly @property in ARC

2019-01-28 00:16发布

问题:

In my interface (.h) file, I have

@property(readonly) NSString *foo;

and in my implementation (.m) file, I have

@synthesize foo;

With ARC turned on, the compiler gives me this error: Automatic Reference Counting Issue: ARC forbids synthesizing a property of an Objective-C object with unspecified ownership or storage attribute.

The error goes away if I add a strong, weak, or copy to the property. Why is this? Why would there be any differences between these things for a read-only property, what are those differences, and why does the programmer have to worry about them? Why can’t the compiler intelligently deduce a default setting for a read-only property?

Another question while I’m at it: strong, weak, or copy are the only things that make sense in ARC, right? I shouldn’t be using retain and assign anymore, should I?

回答1:

You've declared a @property that doesn't have a backing ivar. Thus, when the compiler sees @synthesize, it tries to synthesize a backing ivar for you. But you haven't specified what kind of ivar you want. Should it be __strong? __weak? __unsafe_unretained? Originally, the default storage attribute for properties was assign, which is the same as __unsafe_unretained. Under ARC, though, that's almost always the wrong choice. So rather than synthesizing an unsafe ivar, they require you to specify what kind of ivar you want.



回答2:

With the latest version of Xcode and recent clang compilers, this error no longer occurs. You can specify a property as @property(nonatomic, readonly) NSObject *myProperty; in the interface, synthesize it in the implementation, and the resulting ivar is assumed to be strong. If you want to be explicit or choose weak, you can do so in the original property, like @property(nonatomic, readonly, retain). Objective-C is incrementally becoming less redundant.



回答3:

It is here as a declaration to the rest of your code.
When you a access the property of this class from an other part of your code, you need to know if the object you get is strong or weak.

It used to be more obvious when ARC didn't exists, because the programmer needed this information. Now, ARC makes a lot of things transparent, so it is true, you might wonder why it is still here.


Why can’t the compiler intelligently deduce a default setting for a read-only property?

I assume it would be pretty easy to set the convention that no keyword means strong or means weak. If it hasn't been done, they surely had a reason.