Xcode 4 automatically generates iVars when using #property,where can I find the official doc for this feature? - objective-c

I have read "What's new in Xcode",but I can't find the official explanation for this feature.
Where can I find the official explanation? Which documentation? Thanks.

Assuming you mean that it auto-generates an ivar and getter and setter methods for you even if you omit the #synthesize: this is variously called default property synthesis, automatic property synthesis, and property autosynthesis.
There's not a lot of documentation. As far as I have found, there's no official documentation of how it works, just of the fact that it exists.
It's really a clang feature, not an Xcode feature. It appeared briefly in the version clang shipped with Xcode 4.0 DP 4, but was removed shortly after due to bugs. It reappeared in the version of clang shipped with Xcode 4.4. Here's the commit that added it, I think.
You can find it mentioned in the Objective-C Feature Availability Index.
It's also mentioned in the Clang Language Extensions.
From experimentation:
If you don't explicitly #synthesize a property and it generates an instance variable, it will automatically generate an ivar with the same type (and, under ARC, ownership qualification) as the declared property. The ivar name will be an underscore (_) followed by the declared property name.
If you don't explicitly #synthesize a readonly property, and you do include an explicit getter method, then clang will not automatically generate an ivar for you.
If you don't explicitly #synthesize a readwrite property, and you do include both an explicit getter and an explicit setter, then again clang will not automatically generate an ivar for you.
But I don't know of any official documentation of these behaviors.

You can find this in the Apple documentation in Objective-C Programming Language: Declared Properties under "Property Implementation Directives". Whether or not an ivar is synthesized automatically depends on what runtime you are using:
There are differences in the behavior of accessor synthesis that depend on the runtime (see also “Runtime Difference”):
For the legacy runtimes, instance variables must already be declared in the #interface block of the current class. If an instance variable of the same name as the property exists, and if its type is compatible with the property’s type, it is used—otherwise, you get a compiler error.
For the modern runtimes (see “Runtime Versions and Platforms” in Objective-C Runtime Programming Guide), instance variables are synthesized as needed. If an instance variable of the same name already exists, it is used.
iOS always uses the modern runtime so you never need to declare ivars explicitly.

This is part of the compiler, actually.
You can read that in the LLVM specification website.

I would also draw your attention to the Coding Guidelines for Cocoa which advises:
Avoid explicitly declaring public instance variables.
Developers should concern themselves with an object’s interface, not with the details of how it stores its data. You can avoid declaring instance variables explicitly by using declared properties and synthesizing the corresponding instance variable.

Related

Will the compiler auto-synthesize an ivar for a property declared in a category?

Before so-called "Modern Objective-C", when creating a new property in category, we needed to implement setter and getter methods. Now, we don't have to do #synthesize; the compiler will automatically create the methods and an instance variable.
But normally, we cannot add instance variables to a category, so what happens if we add a new property in a category with modern Objective-C? Does the compiler create an ivar for us?
You can declare a property in a category, which is equivalent to declaring the getter and (if readwrite) setter selectors.
The compiler will not automatically synthesize the getter and setter methods in your category implementation. If you don't explicitly define them in the category implementation, the compiler will issue a warning. You can use #dynamic in the category implementation to suppress the warning. You cannot use #synthesize in the category implementation; the compiler will issue an error if you try.
The compiler will not add an instance variable for a property declared in a category. You cannot explicitly add instance variables in a category, and you can't trick the compiler into doing it using a property.
I tested my claims using Xcode 4.5.1 targetting iOS 6.0.
Actually I don't know when we were able to add property in categories.
From Apple Docs:
A category allows you to add methods to an existing class—even to one for which you do not have the source.
and
Class extensions are like anonymous categories, except that the methods they declare must be implemented in the main #implementation block for the corresponding class. Using the Clang/LLVM 2.0 compiler, you can also declare properties and instance variables in a class extension.
and this method is used to add storage to an object without modifying the class declaration (in case you couldn't modify or don't have access to source codes of class)
Associative references, available starting in OS X v10.6, simulate the addition of object instance variables to an existing class. Using associative references, you can add storage to an object without modifying the class declaration. This may be useful if you do not have access to the source code for the class, or if for binary-compatibility reasons you cannot alter the layout of the object.
So your question for me seems to be incorrect.
Source: Apple Docs - The Objective-C Programming Language
As others have said, the way to do this is with Associative References. They are implemented much like CALayer's value / key-pair paradigm.. in that basically.. you can "associate" anything, with any "property", or "thing"…
So in your category header… if all you want to do is read a value…
#property (readonly) NSString *uniqueID;
and then write your getter…
- (NSString*) uniqueID { return #"You're not special"; }
But say.. you can't just come up with the value from within your getter.. and you need storage for either an external setter… or the class' own implementation to use… you HAVE to write a setter like...
- (void) setUniqueID:(NSString*)uId
It need not be public, necessarily… but this is where the "magic" happens.
…
[self setAssociatedValue:uId forKey:#"yourInternalStorageName"
policy:OBJC_ASSOCIATION_RETAIN_NONATOMIC];
I realized after looking at this, that I'm using some "personal categories" to help ease the setting and getting etc. of these values.. so I've posted them to this gist, as they are VERY useful.. and include such little gems as…
- (id) associatedValueForKey:(NSString*)key
orSetTo:(id)anObject
policy:(objc_AssociationPolicy) policy;
The secret to "getting it" is the "policy" portion.. These values…
OBJC_ASSOCIATION_ASSIGN = 0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
capture the same "personality" traits as are expressed when describing your properties in a "normal" declaration. You must tell the compiler how to "store" your values with those same rules, and you'll be good to go.

How does the new Apple LLVM 4.0 "default synthesize" feature operate?

I was going through the release notes for Xcode 4.4 and noticed this:
LLVM 4.0 Compiler
Xcode now includes the Apple LLVM Compiler version 4.0, including the following newObjective-C language features:
Default #synthesize: automatically synthesizes an #property when unimplemented
I'm intrigued about this feature. How does it work? I have tried by deleting the #synthesize, it doesn't work.
It does work actually, make sure that in your project and target settings the Compiler is set to LLVM 4.0. Then when you delete the #synthesize line you can access it in two ways:
through the accessor with self.myProperty or through the respective instance variable with _myProperty (yeah the underbars are added automatically).
There are many cases where it simply doesn't work. These are all outlined as exceptions here:
http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html
but the most important one, to me, is called
Readwrite Property With Non-Default Getter and Setter
This means that, unless your properties are just public-facing ivars, you need to include a #synthesize. Or to put it another way, if you're using encapsulation well and filling up those setters and getters, you cannot use this.
Later Note: I'm not sure about the conditions specified here, but I find that there is a autosynthesized ivar for just about every situation I encounter.

When to use [self.obj message] vs [obj message] [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
When to access properties with 'self'
In Objective-C on iOS, what is the (style) difference between “self.foo” and “foo” when using synthesized getters?
For example sake, I have a #property named obj and I #synthesize it. So when do I need to use [self.obj message] vs [obj message] in my implementation class.
Using self, the getter method will be called. Thus, any additional logic in this getter method is executed. This is especially useful when instance variables are lazy loaded through their getters.
I myself try to use self most of the time. Lazy loading is just an example, another thing is that with self, subclasses may override the getter to get different results.
Using self to set a variable is even more useful. It will trigger KVO notifications and handle memory management automatically (when properly implemented, of course)
Here are two great tutorials that cover this issue well:
Understanding your (Objective-C) self
When to use properties & dot notation
When synthesize a property, the compiler declare a related ivar for you, in default, the ivar is the same as property name. I recommend use self.obj always to keep code cleaner, and avoid some potential bugs.
And I suggest you follow the good practice from Apple, #synthesize obj=_obj, the ivar will become _obj, when you mean to use property, this style force you to write self.obj, directly call obj will be error since the ivar is _obj.
Edit: automatically creating ivar for property is only in modern Objective-C runtime, it's safe in iOS SDK 4.0 and Mac OS X 10.6 above.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html%23//apple_ref/doc/uid/TP30001163-CH17-SW1
For #synthesize to work in the legacy
runtime, you must either provide an
instance variable with the same name
and compatible type of the property or
specify another existing instance
variable in the #synthesize statement.
With the modern runtime, if you do not
provide an instance variable, the
compiler adds one for you.
In the future, please search the site. You'll often find that the exact question you're asking has been asked before:
difference between accessing a property via "propertyname" versus "self.propertyname" in objective-c?
When to access properties with 'self'
self.variable and variable difference
Objective-C: When to call self.myObject vs just calling myObject
iVar property, access via self?
Should I Use self Keyword (Properties) In The Implementation?
In Objective-C on iOS, what is the (style) difference between "self.foo" and "foo" when using synthesized getters?
When to use self on class properties?
... etc.

Objective-C properties, how do they work?

Assume we have a class Foo with a property bar.
Declared like this in the header:
#interface Foo : NSObject {
int bar;
}
#property (nonatomic, assign) int bar;
#end
In the .m I have #synthesize bar; of course.
Now, my question is, if I remove the int bar; line, the property behaves the same way, so, is that line really necessary? Am I missing some fundamental concept?
Thanks!
The "modern" Objective-C runtime generates ivars automatically if they don't already exist when it encounters#synthesize.
Advantages to skipping them:
Less duplication in your code. And the #property gives the type, name and use (a property!) of the ivar, so you're not losing anything.
Even without explicitly declaring the ivar, you can still access the ivar directly. (One old release of Xcode has a bug that prevents this, but you won't be using that version.)
There are a few caveats:
This is not supported with the "old" runtime, on 32-bit Mac OS X. (It is supported by recent versions of the iOS simulator.)
Xcode may not show autogenerated ivars in the debugger. (I believe this is a bug.)
Because of the debugger issue, at the moment I explicitly add all my ivars and flag them like this:
#interface Foo : NSObject {
#ifndef SYNTHESIZED_IVARS
int ivar;
#endif
}
#property (nonatomic, assign) int bar;
#end
My plan is to remove that block when I've confirmed the debugger is able to show the ivars. (For all I know, this has already happened.)
If there is not a instance variable (ivar) with the same name as the property the modern runtime creates a new ivar of the specified property name to hold the property value when it sees #synthesize.
If your property was not defined nonatomic and you want your code to be threadsafe it may help you to not reference the ivar (whether you declared it or it was synthesized), as that will prevent you from accessing it directly when the property is being changed. To my knowledge there is no way to acquire the same lock that is acquired by #synthesize for an atomic property and therefore you cannot perform safe reads of an atomic property's ivar other than by its synthesized accessor (unless you code an explicit setter and lock something yourself). If you are interested in writing you own accessors I have a blog post on that here.
I believe it is more usual to have an explicit ivar for each property, but this may be because most code is intended to be compatible with the legacy runtime rather than because it is inherently good practice.
Edit: I have corrected paragraph 1 to say that the synthesized ivar has the name of the property; I couldn't see any discussion of its name in Apple's docs so I had assumed it was not user accessible. Thanks to the commenters for pointing this out.
In the latest Objective-C runtime, it turns out that all ivars (in this case, bar) are dynamically added to the class from the #property/#synthesize declaration and do not need a corresponding ivar declaration in the class header. The only caveat to this is that latest Objective-C runtime which supports this feature does not include support for 32 bit applications.
This page from the excellent Cocoa with Love blog explains more.
If you are using the modern Obj-C runtime (e.g. with the LLVM compiler in Xcode 4), the compiler can automatically create the instance variable for you. In that case, you don't need to declare the ivar.
The modern runtime is supported by iOS, the iOS Simulator and 64-bit Mac OS X. You can't build your project for 32-bit OS X with the modern runtime.
I believe it only works that way in 64bit mode. If you try to build for a 32bit target, it will throw an exception.
Scott Stevenson has a good overview of the objective-c 2 changes, and mentions the 64bit runtime changes here

Quirk with Core Data, protocols, and readwrite vs. readonly property declarations

I'm running into an odd quirk involving Core Data, a declared protocol, and perhaps the LLVM 1.5 compiler. Here's the situation.
I have a Core Data model that among others has two classes, IPContainer and IPEvent, with IPContainer being the parent entity of IPEvent. Each entity has a custom class in the project for it, created using mogenerator. mogenerator generates an additional subclass that just contains the modeled property declarations, so the class hierarchy is actually IPEvent > _IPEvent > IPContainer > _IPContainer > NSManagedObject. The IPContainer entity has an attribute named 'id', which is declared as #property(nonatomic, retain) NSNumber* id; in _IPContainer.h. _IPContainer.m has #dynamic id; in the implementation, to tell Core Data to generate the accessors at runtime
I also have a protocol IPGridViewGroup declared in my project which defines several properties, one of which is that same 'id' property. However, a setter is not necessary for classes implementing this protocol, so the property in the protocol is declared as #property(readonly) NSNumber* id; The IPEvent class declares that it conforms to the IPGridViewGroup protocol.
This worked fine using the Clang/LLVM 1.0.x compiler (whichever version shipped with Xcode 3.2.2), but upon upgrading to Xcode 3.2.3 and Clang/LLVM 1.5, a whole bunch of things changed. First, I get the following warning when compiling the IPEvent class:
/Volumes/Ratbert/Users/bwebster/Projects/UberProject/iPhotoLibraryManager/IPGridViewGroup.h:19:31: warning: property 'id' requires method 'id' to be defined - use #synthesize, #dynamic or provide a method implementation
Then, when I actually run the program, this gets printed out in the console:
Property 'id' is marked readonly on class 'IPEvent'. Cannot generate a setter method for it.
Followed shortly by:
-[IPEvent setId:]: unrecognized selector sent to instance 0x200483900
I also tried redeclaring the property on the IPEvent class, but that just gave me a different compiler warning, and the same behavior at runtime:
/Volumes/Ratbert/Users/bwebster/Projects/UberProject/iPhotoLibraryManager/IPManagedObject/IPEvent.h:14:40: warning: property 'id' 'retain' attribute does not match the property inherited from 'IPGridViewGroup'
Now, the only thing that's changed here is the compiler, so the catalyst for the change is clear, but what I don't know is whether this could be considered a bug in the new version of the compiler, or if the old version of the compiler was actually behaving incorrectly, and the new version now reveals that it's my own code that's buggy.
So among the questions I have here are:
It seems like it should be OK to have a class conform to a protocol with a readonly property, but provide readwrite access for the property in its own implementation, is that correct? The quirk here though is that the readwrite property is actually declared in the superclass of the class that conforms to the protocol.
I'm assuming that console message is being printed out somewhere in the bowels of Core Data. This is odd though, because IPEvent itself doesn't declare the 'id' property explicity, except by conforming to the IPGridViewGroup protocol. However, if this is the case, then I would think a compiler error would come up, since it would effectively being overriding a readwrite property (declared in the _IPContainer superclass) with a readonly version of the same property, which AFAIK is normally not allowed.
If this is a compiler bug, then fine, I can work around it in a couple different ways for now. If the compiler is doing the right thing here though, then I'm at a loss to come up with a way to organize all this so I don't get any compiler warnings or runtime errors.
Edit: so, the workaround is to redeclare the property again on the IPEvent class, but I'm still puzzled as to why the two versions of the compiler act differently. It's also unclear how exactly properties declared on a protocol are supposed to interact with those declared on a class.
If I declare a readonly property in the class (rather than the protocol) overriding a readwrite property, I get the message "warning: attribute 'readonly' of property 'longitude' restricts attribute 'readwrite' of property inherited from '_IPEvent'". It seems like if declaring it in the protocol has the same effect, a similar warning should come up from the compiler.
Intuitively though, I would think that since IPEvent already implements the necessary getter for the property, that should count as "conforming to the protocol", even if it happens to also implement a setter for the property.
Now, the only thing that's changed
here is the compiler, so the catalyst
for the change is clear, but what I
don't know is whether this could be
considered a bug in the new version of
the compiler, or if the old version of
the compiler was actually behaving
incorrectly, and the new version now
reveals that it's my own code that's
buggy.
The newer compiler has noticed that you have two separate definitions for the accessors for the same instance variable of the same class. Of course, the linker should complain.
The old compiler should have kicked this back. The #property declaration is an implicit method declaration whether it occurs in a class or a protocol. When you have both a class and a protocol define a property with the same name, you end up with two sets of method declarations for one class. This is obviously going to cause problems somewhere along the line.
The differences between the two compilers could be something trivial such as the order of the #import statements in source or even the modification dates on the source files.
You're obviously getting a collision because the IPContainer class has two dynamic method definitions, one generates just a setter and the other a setter and a getter. How should the compiler know which one to use? You've just told it that you want a readonly readwrite property. Worse, since this is a dynamic property, there is no telling what will actually be generated at runtime.
1 It seems like it should be OK to
have a class conform to a protocol
with a readonly property, but provide
readwrite access for the property in
its own implementation, is that
correct?
Define "OK". Will the compiler accept it? Probably. After all, in a readonly property in the protocol you've defined a getter method but in the class you've also defined a setter method. Since a protocol doesn't restrict what additional methods an implementing class can have, the setter method can be added just like you could add any other unrelated method.
However, this is obviously very, very dangerous, especially in the case of NSManagedObject subclasses. The managed object context has very firm expectations about what it expects to find in the classes it works with.
2 This is odd though, because IPEvent
itself doesn't declare the 'id'
property explicity, except by
conforming to the IPGridViewGroup
protocol.
If the property is required by the protocol, it is explicitly declaring it by adopting the protocol.
3 If this is a compiler bug, then
fine, I can work around it in a couple
different ways for now. If the
compiler is doing the right thing here
though, then I'm at a loss to come up
with a way to organize all this so I
don't get any compiler warnings or
runtime errors.
The simplest solution is (1) Don't define protocols that overlap class properties. Doing so defeats the entire purpose of having a protocol anyway. (2) Make the protocol property readwrite so the compiler and the runtime are not confused.
Intuitively though, I would think that
since IPEvent already implements the
necessary getter for the property,
that should count as "conforming to
the protocol", even if it happens to
also implement a setter for the
property.
You could probably get away with it if your weren't using dynamic properties. With a dynamic property the complier has to generate a message to the runtime explaining what accessors to generate on the fly. What's it supposed to say in this case? "Generate a method that conforms to the readonly protocol but by the way make it readwrite at the same time?"
No wonder the compiler is complaining. If it was a dog, it would be wetting itself in confusion.
I think you need to seriously rethink your design. What possible benefit can you gain from such a non-standard, risky design? Getting compiler errors is the best case scenario. In the worst case, the runtime gets confused with unpredictable results.
In short, (with apologies to Shakespeare) "...the fault lies not in the complier but with ourselves."
Let's try and break this down a bit. If I understand correctly:
IPEvent is a class which inherits _IPEvent and implements IPGridViewGroup.
IPGridViewGroup has a readonly property id.
_IPEvent inherits the readwrite property id from _IPContainer.
Assuming those assumptions are correct (and please tell me if I'm wrong) then IPEvent has inherited two different id properties, one of which is readonly and one of which is not.
Did you try redefining the id property in IPEvent with the explicit readwrite modifier?
ex:
#property (nonatomic, retain, readwrite) NSNumber *id;
Hopefully then the compiler will get the hint and generate a setter.
#property(readonly) NSNumber* id
Looks incorrect. Core Data docs say you should use nonatomic (since you can't use threading here), and you should also be retaining id since it's an object, not assigning it (the default).
If a subclass needs to access an ivar of a superclass it needs to declare its property and use #dynamic to tell the compiler to be quiet. It does not look like you are doing that.
It could also be connected with this bug I found that varies between compilers:
http://openradar.appspot.com/8027473 Compiler forgets superclass ivar exists if a prop without an ivar is declared
It is also possible that id has a special meaning in Core Data and you should use a different name.