Omitting Memory Management attributes - ios

With the latest versions of xCode and LLVM compliers , it is possible to omit the memory management attributes when declaring properties etc,
#property(copy) NSString *myString can be declared as ,
#property NSString *myString;
Will the myString would use "copy" as the default attribute or "Strong" ?
Is there any place where can I find the default values ? etc. Will
#property BOOL myBoolValue will use assign ?

Primitive data has no reference count, therefore you cannot use Strong or Weak with it, so you can only use assign, that is the default value
For objects, the default value in ARC is strong

Object properties are strong by default. Reference: http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

In projects that do not use ARC (and therefore use manual memory management) the default attributes for properties are (atomic, assign). From Xcode 4.4+ (or 4.5+ I don't remember exactly which), in projects using ARC the default attributes are (atomic, strong), though!
For NSStrings, therefore, it will also use strong, and not copy.
Check this: http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Related

Why Obj-C property default ownership "assign" instead of "strong"

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.

Whether I should use #property(nonatomic,copy) or #property(nonatomic,strong) for my (NSString *) attr in An object?

#interface PaneBean : NSObject
#property(nonatomic,copy) NSString *name;
#property(nonatomic,copy) NSString *type;
#property(nonatomic,assign) NSInteger width;
#end
I have a PaneBean as is shown above.
Whether I should use #property(nonatomic,copy) or #property(nonatomic,strong) for my (NSString *) name? What is the difference between them?
And is it right to write 'assign' for NSInteger?
Any help appreciated.Thanks in advance!
'copy' will cause the setter for that property to create a copy of the object, and is otherwise identical to strong. You would use this to make sure that if someone sets your property to a mutable string, then mutates the string, you still have the original value. If the string isn't mutable, Cocoa will silently optimize out the copy operation, which is nice :)
'strong' will keep the property's value alive until it's set to something else. If you want incoming mutable strings to change out from under you (not impossible, but not all that common, a thing to want), then strong would be the right thing to do. Generally strong is more useful for objects that represent something more complex than a simple "value" (i.e. not NSString, NSNumber, NSValue, etc...).
'assign' is the default (and indeed only) possible setting for an integer. Integers can't be retained or copied like objects.
For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your #property declaration. Specifying retain is something you almost never want in such a situation.In non ARC strong will work like retain
Here's why you want to do that:
NSMutableString *someName = [NSMutableString stringWithString:#"Chris"];
Person *p = [[[Person alloc] init] autorelease];
p.name = someName;
[someName setString:#"Debajit"];
The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be #"Debajit" if the property is marked retain, but #"Chris" if the property is marked copy.
Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using #synthesize you should remember to actually use copy instead of retain in it.)
copy sends the copy message the object you set, while strong only retains it (increments the reference count).
For NSString , or in general any inmutable class with known mutable subclasses(NSArray, NSDictionaty, NSSet), copy is preffered to avoid clients setting a mutable instance and modifying it out of the object.
For primitive types(int for example) copy/strong does not make sense and by default assign is used. Is up to you if you want to put it explicitly or not.
Strong indicates composition, while Weak indicates aggregation.
Copy means that a new object is to be created before the contents of the old object are copied into the new object. The owning object, PaneBean in this case, will be composed of the newly created object.

iOS property declaration clarification

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

What are the defaults values for #property in iOS?

What are the defaults values for #property in iOS ?
For example, if I declare #property NSString* photographer;
is the default value (assign) or (retain) or what else ?
(atomic, non-atomic) ?
I cannot find this information from the documentation.
thanks
I believe the defaults are (atomic, assign), however, you should not leave them empty.
The default may change at any point, and you're writing code that is relying on the definition of the property.
For example, if you rely on the default assign and it changes to retain for whatever reason in the future, then all of your code is going to leak.
Conversely, if the default is retain and you rely on that and it changes to assign, then your code is going to crash when you inevitably over release an object.
Do not rely on any default, regardless of what they may be.
Explicitly define your properties' attributes.
Properties are atomic by default so that synthesized accessors provide robust access to properties in a multithreaded environment—that is, the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently.
If you specify strong, copy, or retain and do not specify nonatomic, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value.
I don't think Apple will change it in the future, but unfortunately the most common is non atomic, so you may have to write it down.

Objective-C 101 (retain vs assign) NSString

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.

Resources