I'm adding Swift classes to an old project. It went well, until I tried adding a property to the Swift class. The generated header doesn't compile.
I think the problem is, in the generated code, Swift omitted strong ownership and only declared it as nonatomic. This should normally be enough, because #property should default to strong ownership, right?
So basically these are equivalent:
#property (nonatomic) NSDate *aDate;
#property (nonatomic, strong) NSDate *aDate;
But, in my case, it seems like it is defaulting to assign instead of strong, according to the compiler message.
I'm using Xcode 6 GM, and the project has ARC turned on.
Any idea why it is not defaulting to strong? Can I change this somehow?
After numerous experiments, I've found out a subtlety that determines the default ownership behavior of a property:
If a header file is imported only into ARC-enabled classes, and there is no default ownership declared, then the ownership of the property within this header file is strong.
If a header file is imported into at least one non-ARC class, and there is no default ownership declared, then the ownership of the property is assign!
This means also, you must not import a -Swift.h header into any non-ARC classes, as it will change the behavior of all the properties and emit warnings (which in my case were converted to errors).
Pretty weird IMHO...
Example:
we have classes SourceClass, ARCClass(ARC-enabled) and MRCClass(ARC-disabled)
SourceClass.h has: #property (nonatomic) NSDate *date;
Subtlety:
If we add #import "SourceClass.h" only in ARCClass.h or ARCClass.m,
the property date has ownership strong.
the declaration is equivalent to #property (nonatomic, strong) NSDate *date;.
As soon as we add #import "SourceClass.h" to MRCClass.h or MRCClass.m,
the property date will have ownership assign instead.
the declaration is changed to #property (nonatomic, assign) NSDate *date;.
I'm sure that, at one time, "assign" was the default and this...
http://cagt.bu.edu/w/images/b/b6/Objective-C_Programming_Language.pdf
"assign -
Specifies that the setter uses simple assignment. This is the default."
...seems to confirm that (page 59).
However, I also see an Apple document ("Programming with Objective-C") that says, "By default, both Objective-C properties and variables maintain strong references to their objects". I believe the change was made with the introduction of ARC.
Although you say ARC is turned on, if this project is old enough it may be that something is still around to interfere with ARC settings.
I realize this isn't a definitive answer but perhaps checking project settings (or cleaning up the project) with this change in mind may help.
Related
I've been doing Objective-C programming for a few years now. I was listening to a podcast the other day which mentioned something about how Apple has made it easier over the years, and I thought I heard mention of there being no need to manually add instance variables now. Is this true? Here's how I do it currently:
.h:
#interface Class : UIView
#property (nonatomic, strong) NSString *testString;
#end
.m:
#interface Class () {
NSString *_testString;
}
#end
#implementation Class
#synthesize testString = _testString;
Is this work necessary?
This is all you need now
.h:
#interface Class : UIView
#property (nonatomic, strong) NSString *testString;
#end
.m:
#implementation Class
#end
#property will automatically create an instance variable now, and #synthesize is automatically added unless you specify otherwise. So yes, just a #property is enough.
Nope, it will auto-synthesize in Xcode 4.4+
You can read more about it here.
Although you don't need to type that boilerplate code for non-#dynamic properties since LLVM 4.0 (Xcode 4.4+), it's a good thing to know that it is a compiler feature, not part of the language (Objective C), nor the runtime system. The runtime system still rely on instance variables and getters/setters generated by the #synthesize directive. It's the compiler who is able to generate the code for you, pretty much like it is able to follow conventions and generate calls to retain and release in ARC code.
So, it is important to notice that, if you are going to share your project with other developers using older versions of Xcode (specifically, older versions of the Clang/LLVM compiler), you must synthesize your variables or the project will not compile in their machines or will fail at runtime.
All of that work is unnecessary.
Just declare the property, it will automatically default to creating an instance variable with the underscore convention. Though, self.property may tickle your fancy as well.
You can do the same for private properties by declaring them in an interface extension in the .m file.
#synthesize-ing is no longer necessary. #dynamic is still necessary if I understand correctly
I declared a property as below. From my readings on the web, it is not clear if I should also synthesize as below. I have seen supporting blog posts for two different approaches.
#property (assign, nonatomic) CGFloat someFloat;
Then in the implementation:
#synthesize someFloat = _someFloat;
I have also seen in some cases:
#synthesize someFloat;
From readings, I understand that "someFloat" is a property name, and "_someFloat" is created through the synthesis. So I am under the impression that the first way is correct. However, I have used the second approach without problems. And I have seen the second approach in other code and blogs.
Can someone tell me what is the correct way and why?
In general, you no longer need to manually write #synthesize anymore. In your example, if you write
#property (assign, nonatomic) CGFloat someFloat;
The compiler will automatically synthesize it for you, which would be equivalent to you writing
#synthesize someFloat = _someFloat;
Hence, you would be able to access the property through self.someFloat or access the ivar within the implementation file by using _someFloat.
If, however, you manually synthesize it like
#synthesize someFloat;
The compiler automatically creates a backing ivar titled someFloat... thereby, you would still be able to access the variable through the getter self.someFloat (that is, equivalent to [self someFloat] call).
Or, you could access the ivar by simply using someFloat somewhere within the implementation...
In general, it's not recommended to synthesize like this because it's quite easy to accidentally use the ivar when you meant to access the variable using the getter.
EXCEPTION TO THE RULE
The compiler still gets confused with synthesizing variables sometimes, however, in certain instances. For example, if you have a class that is a subclass of NSManagedObject, then you still need to write the #synthesize manually (assuming, of course, you actually want to synthesize the property... you likely don't though...).
The reason for this is two-fold: (1) the compiler doesn't seem to understand these properties very well yet (or at least it doesn't in the cases I've worked with), and (2) many times, you actually DON'T want to #synthesize properties on an NSManagedObject subclass... rather, you want them to be #dynamic instead (so the getter/setter will be generated at runtime, per requirements of NSManagedObject subclass magic).
Just skip the #synthesize statement, the compiler will generate the same thing as if you had:
#synthesize someFloat = _someFloat;
approach 1:
#interface MyController : UIViewController {
UILabel *myText;
}
#property (nonatomic, strong) UILabel *myText;
approach 2:
#interface MyController : UIViewController
#property (nonatomic, strong) UILabel *myText;
approach 3:
#interface MyController : UIViewController {
UILabel *myText;
}
I have read some articles talking about this kind of stuff but I still do not really realize which approach I have to adopt.
I also found that someone said approach 1 is a old way so I would like to know the best practice for ios sdk 6 using ARC.
I know that declaring variables using property is a easy way for generating getter and setter and someone suggested using it. However, I would like to ask in case a variable is not for calling by another class, is it necessary for the variable using property? and set it as private variable inside the interface? Or is it better for a variable only declaring inside the interface? I would like to learn the best practice so please forgive me if this is a silly question.
Moreover, some developers write #synthesize in this way
#synthesize myText=_myText;
but some write this:
#synthesize myText;
I would also want to know the difference and which one is preferable?
Thank you very much!
The most modern way1:
whenever possible, declare properties
don't declare iVars separately 2
don't #synthesize 3
locate as few properties as possible in you .h file 4
locate as many properties as possible in a class extension in your .m file 5
1 As of Xcode 4.5.2. Most of this applies back to 4.4, some of it won't compile on 4.2 (the last version available under Snow Leopard). This is preprocessor stuff, so it is all compatible back at least to iOS5 (I haven't tested on iOS4 but that should also be OK).
2 There is no point in declaring an iVar as well as a property. I am sure there are a few obscure cases where you would want to declare iVars instead of properties but I can't think of any.
3 Xcode will create an iVar with the same name as the property, preceded by an _underscore. If you (rarely) need some other kind of behaviour, you can manually #synthesize property = someOtherName. #vikingosegundo links us to this article on dynamic ivars, which is a use case for #synthesize. #RobNapier comments that you do need to #synthesize iVar = _iVar (bizarrely) if you are creating your own getters (readonly) and setters (read/write) for a property, as in this case the preprocessor will not generate the iVar for you.
4 The general rule with your interface: keep it as empty as possible. You don't actually need to declare your methods now at all, if they are for private use. If you can get the code to work without an interface declaration, that's the way to go.
5 This is an #interface block in your .m file, placed above your #implementation:
#TestClass.m
#interface TestClass()
//private property declarations here
#end
#implementation TestClass
...
You may also want to use #synthesize if you like a nice table of contents of your #synthesized properties that you can refer to and comment for clarity and organization.
Also, an #synthesize allows you to set a breakpoint on the property and trap when its value is changed.
When the compiler does everything for you, you end up being distanced from what is really happening and ignorant to it. However, not having to type out everything yourself all the time is also nice.
This is a two part question in hopes that I can understand more about the topic.
1) It seems to me that you have two popular options for declaring a property for a class in objective c. One is to add the property to the header's class body eg.
#interface MyClass : NSObject {
NSArray *myArray;
}
Or you can add it after the #interface body and before the #end statement like so.
#interface MyClass : NSObject {
//
}
#property (nonatomic, retain) NSArray *myArray;
What is the difference between these two "styles" and when do you choose one over the other?
2) after the #property you find options such as (nonatomic, retain). What are those for and why/when do you use different options?
Here are the only property modifiers that Xcode recognizes:
nonatomic (does not enforce thread safety on the property, mainly for use when only one thread shall be used throughout a program)
atomic (enforces thread safety on the property, mainly for use when multiple threads shall be used throughout a program) (default)
retain / strong (automatically retains / releases values on set, makes sure values do not deallocate unexpectedly) (default if ARC and object type)
readonly (cannot set property)
readwrite (can both set and get property) (default)
assign / unsafe_unretained (no memory management shall be done with this property, it is handled manually by the person assigning the value) (default if not ARC or object type)
copy (copies the object before setting it, in cases where the value set must not change due to external factors (strings, arrays, etc).
weak (automatically zeroes the reference should the object be deallocated, and does not retain the value passed in)
getter=method (sets the selector used for getting the value of this property)
setter= method (set the selector used for setting the value of this property)
1) #property is a special way to define getter- and setter-methods, or as we call them accessors in Objective-C. Your first snippet just declares an array for which you have to declare and write accessors yourself. For example setMyArray: and myArray.
Using #property will declare your accessors for you and is equivalent to declaring setMyArray: and myArray yourself. It is the preferred way to declare accessors since Objective-C 2.0. Note that you still have to declare the property (in your case myArray) yourself.
2) You first need to know about #synthesize. Remember that #property DECLARES the accessors for your property, #synthesize will IMPLEMENT them. When you use an #property in your #interface you mostly likely write an #synthesize in #implementation. Using #synthesize is equivalent to implementing setMyArray: and myArray.
The attributes (nonatomic, retain) tell the compiler, among others, how the memory management should work and therefore how the methods will be implemented. Note that you never actually see these accessors, but be assured that they are there and ready for you to be used.
To read more on that topic I recommend reading Section 9 on Properties from the following Tutorial or buy a Book that covers an Introduction to Objective-C.
Also you should familiarize yourself with at least the following attributes:
Access
Choose readwrite (default) or readonly. If readonly is set, ONLY the getter methods will be available.
Setter Memory Management
assign (default), simply assigns the new value. You mostly likely only use this with primitive data types.
retain, releases the old value and retains the new. If you use the garbage collector, retain is equivalent to assign. Why? The manual release of the old value will be done by the garbage collector.
copy will copy the new value and release the old value. This is often used with strings.
Threading
atomic (default) will ensure that the setter method is atomic. This means only one thread can access the setter at once.
nonatomic, use this when you don't work with threads.
This post gives you a good introduction to memory management and assign, retain and copy.
Properties are basically the accessor methods. They define the scope of the variable.
First case as given above,the variable is not accessible in other classes whereas by declaring a property as in the second case,variable is accessible in other classes also.
Also, they are useful for memory management.
First one will be private declaration and will not be accessible by other classes if you do not define the second one. Second is used together with #synthesize in .m module , and setter/getter's are created for you by the compiler. You can still define your own getter or setter with this. In this case all iVars defined in #property can be accessed by other classes.Retain/release operations are done automatically.
You should read Apple documentation for more details.
please check:
What's the difference between the atomic and nonatomic attributes?
Properties are basically the accessor methods. They define the scope of the variable. by default access specifior of variable is protected and properties set its Specifier from protected to Public
A 101 question
Let's say i'm making database of cars
and each car object is defined as:
#import <UIKit/UIKit.h>
#interface Car:NSObject{
NSString *name;
}
#property(nonatomic, retain) NSString *name;
Why is it #property(nonatomic, retain) NSString *name; and not #property(nonatomic, assign) NSString *name;?
I understand that assign will not increment the reference counter as retain will do. But why use retain, since name is a member of the todo object the scope of it is to itself.
No other external function will modify it either.
There's no such thing as the "scope of an object" in Objective-C. Scope rules have nothing to do with an object's lifetime — the retain count is everything.
You usually need to claim ownership of your instance variables. See the Objective-C memory management rules. With a retain property, your property setter claims ownership of the new value and relinquishes ownership of the old one. With an assign property, the surrounding code has to do this, which is just as mess in terms of responsibilities and separation of concerns. The reason you would use an assign property is in a case where you can't retain the value (such as non-object types like BOOL or NSRect) or when retaining it would cause unwanted side effects.
Incidentally, in the case of an NSString, the correct kind of property is usually copy. That way it can't change out from under you if somebody passes in an NSMutableString (which is valid — it is a kind of NSString).
and don't forget to access it via
self.name = something;
because
name = something;
will not care about the generated setter/getter methods but instead assign the value directly.
Without retain there is no guarantee the NSString* you are setting name with will live any longer than the assignment statement itself. By using the retain property for the synthesized setter you're allowing it to tell the memory management system that there is at least one more object interested in keeping the NSString* around.
For those who are looking for it, Apple's documentation on property attributes is here.
The self. in:
self.name = something;
is important! Without it, you are accessing the variable directly and bypassing the setter.
The older style (correct me if I am wrong) would have been:
[self setName:something];
Anyway, this notation was the (vaguely familiar sounding) advice that I really needed when I went looking for proper #properties on NSStrings. Thanks Axel.
After reading so many Articles, SO posts and made demo apps to check Variable property attributes, I decided to put all the attributes information together
atomic //default
nonatomic
strong=retain //default
weak= unsafe_unretained
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
so below is the detailed article link where you can find above mentioned all attributes, that will defiantly help you.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
retain = strong
it is retained, old value is released and it is assigned
retain specifies the new value should be sent -retain on assignment and the old value sent -release
retain is the same as strong.
apple says if you write retain it will auto converted/work like strong only.
methods like "alloc" include an implicit "retain"
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
assign
assign is the default and simply performs a variable assignment
assign is a property attribute that tells the compiler how to synthesize the property's setter implementation
I would use assign for C primitive properties and weak for weak references to Objective-C objects.
Example:
#property (nonatomic, assign) NSString *address;
#synthesize address;
Google's Objective-C Style Guide covers this pretty well:
Setters taking an NSString, should always copy the string it accepts.
Never just retain the string. This avoids the caller changing it under you without your knowledge. Don't assume that because you're accepting an NSString that it's not actually an NSMutableString.
Would it be unfortunate if your class got this string object and it then disappeared out from under it? You know, like the second time your class mentions that object, it's been dealloc'ed by another object?
That's why you want to use the retain setter semantics.