I want to use ARC in my simple class where I store some values to pass into another class. And I want to know what reference I have to use in the property. To use it in ARC, I have this:
#interface MyItem : NSObject
#property (retain) NSString *valueID;
#property (retain) NSString *itName;
#property (retain) NSDate *creationDate;
#property (assign) float rating;
This is a very simple class, and I want to know how to use it in ARC. What reference do I have to use? Do I have to use a copy for the NSString etc?
EDIT:
If I have a UIViewController, and I want to use a property for NSString and for MyItem object like this:
#interface MyViewController : UIViewController
#property (nonatomic, retain) NSString *myString;
#property (nonatomic, retain) MyItem *newItem;
What reference do I have to use for NSString and for MyItem object?
You want to use strong instead of retain. And yes, you should still use copy for NSStrings. The use of copy has nothing to do with ARC; you want copy because if someone assigns an NSMutableString to your property you don't want the string changing behind your back. Using copy gives you an immutable snapshot of the mutable string at the point where the assignment took place.
This is the recommended way to declare the properties in your view controller example:
#interface MyViewController : UIViewController
#property (nonatomic, copy) NSString *myString;
#property (nonatomic, strong) MyItem *newItem;
The NSString could be declared as strong as well, but copy is almost always preferable for strings (and really any immutable type that has a mutable variant, e.g. arrays, dictionaries, etc).
(nonatomic, strong) is what i use but here is the documentation
or for quick reference
Setter Semantics
These attributes specify the semantics of a set accessor. They are
mutually exclusive.
strong Specifies that there is a strong (owning) relationship to the
destination object.
weak Specifies that there is a weak (non-owning) relationship to the
destination object.
If the destination object is deallocated, the property value is
automatically set to nil.
(Weak properties are not supported on OS X v10.6 and iOS 4; use assign
instead.)
copy Specifies that a copy of the object should be used for
assignment.
The previous value is sent a release message.
The copy is made by invoking the copy method. This attribute is valid
only for object types, which must implement the NSCopying protocol.
assign Specifies that the setter uses simple assignment. This
attribute is the default.
You use this attribute for scalar types such as NSInteger and CGRect.
retain Specifies that retain should be invoked on the object upon
assignment.
Atomicity
You can use this attribute to specify that accessor methods are not
atomic. (There is no keyword to denote atomic.)
nonatomic Specifies that accessors are nonatomic. By default,
accessors are atomic.
Related
I'm starting my adventure with Objective-C and iOS and I've got one thing that I don't know how to use correctly and this is literally blowing my mind.
Many tutorials have private class variables in .m files defined like this:
#interface ViewController (){
#property (nonatomic, strong) NSMutableArray *myArray;
}
or like this:
#implementation ViewController
NSMutableArray *myArray;
#end
In the first example I can use _myArray instead of self.myArray, which I like, but should I put all my private variables in interface files? What's the difference between those two variables? When should I use one instead of another, and which is safer?
The difference is that:
_myArray is instance variable.
self.myArray is calling a getter method on your object.
Using self.myArray = nil makes the variable go through its setter and therefore release the object when ARC is not used).
If the property is declared with atomic (default value) which means access the variable is thread-safe with the cost of performance
nonatomic property means race condition can happen when access the variable or property from multiple threads.
In general, use atomic for object shared with multiple threads and nonatomic for UI or not shared object.
Attention, you will get compiler error with your code:
#interface ViewController (){
#property (nonatomic, strong) NSMutableArray *myArray;
}
-> you must move #property... outside of {} of your header.
#interface ViewController (){
//
}
#property (nonatomic, strong) NSMutableArray *myArray;
A couple of thoughts:
The first example is not syntactically correct. You probably meant the following, which defines a declared property inside the class extension:
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *myArray;
#end
A property will:
Synthesize an instance variable called _myArray (or if you specify a #synthesize directive, you can control the name of this instance variable);
Synthesize accessor methods, notable a myArray getter that retrieves the value and a setMyArray setter that sets the value;
Provide other features such as key-value coding, etc.
On the other hand, the following declares a global variable:
#implementation ViewController
NSMutableArray *myArray;
#end
Globals are a very different beast, shared amongst all of the various instances of this class (and across the whole app). In this case (some mutable array used by a class instance), a global is likely not what you intended.
If you intended to define an instance variable, you could do:
#implementation ViewController
{
NSMutableArray *myArray;
}
#end
Or, perhaps better than defining this ivar in the #implementation like that, one would generally define them within the class extension's #interface:
#interface ViewController ()
{
NSMutableArray *myArray;
}
#end
I suspect you didn't actually intend to compare the global variable to a instance variable (ivar) or property, but rather were asking the rationale for privately using a property vs. ivar within a class implementation:
Bottom line, within a particular class, using ivars is a perfectly acceptable practice, but many of us use private properties defined in class extensions. The overhead is minimal and it abstracts the code away from the implementation details of the ivar. For example, you can customize one or more of the accessor methods at some future date and have minimal impact on the rest of the class implementation. But it's a matter of personal preference.
#property creates your setters and getters the other one does not.
yes, #property is automatically creates setter and getter.
additionally, you can setting property's attribute.
(read-only/readwrite, nonatomic/atomic, strong/weak.. etc)
accessing instance variable by getter & setter(instead of using pointer to direct access) make data encapsulated.
it is common and important concepts of Object-Oriented Programming.
read this for understanding.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
sorry for poor english. :<
I'm beginning to learn how use Core Data for my app, and I have a question about setter and getter with NSManagedObject.
In my old models I was using this syntax to declare attributes :
#interface MyModel : NSObject
{
MyAttributeOfClass *_myAttributeOfClass
}
- (void)setMyAttributeOfClass:(MyAttributeOfClass *)anAttributeOfClass;
- (MyAttributeOfClass *)myAttributeOfClass;
I know, I could use #synthesize for doing this stuff. But if I use #synthesize with a public attribute like :
#property (nonatomic, strong) MyAttributeOfClass *myAttributeOfClass;
A developer could bypass my setter and directly set a value for myAttributeOfClass by doing this: myAttributeOfClass = bar;. I don't want to allow this behaviour because I use a setter to perform an action. If this action is not done, my class will no longer work correctly.
So, now I am migrating my old model to Core Data model subclassed from NSManagedObject.
But when I generate classes from my data model, the attributes are declared this way:
#property (nonatomic, retain) MyAttribute *myAttribute;
So, a developer can set a value for this attribute without calling a setter: myAttribute = bar; and I would like forbid it.
Any suggestions ?
Thanks !
The attributes of Core Data managed objects are not backed-up by instance variables. An attribute can be set using the property syntax:
object.myAttribute = bar;
or with Key-Value Coding:
[object setValue:bar forKey:#"myAttribute"];
and in both cases the setter method
-(void)setMyAttribute:(MyAttribute *)value;
is called. Setter and getter method are usually created dynamically at runtime, but you
can provide your own explicit setter and/or getter method.
However, it is possible to bypass the setter by calling the "primitive" accessor methods:
[object setPrimitiveValue:bar forKey:#"myAttribute"];
This is what a custom setter method would use, but anybody can call the primitive accessor,
there is no way to inhibit that.
My approach when I want to have a private setter is to have this in the header:
#property (nonatomic, strong, readonly) NSString* myProperty;
And then in the .m file add:
#interface MyClass ()
#property (nonatomic, strong) NSString* myProperty;
#end
Externally the property is read-only, but by defining a private category in the implementation file, the property is readwrite within the implementation.
Finally I'm transitioning to ARC. Sounds too late but all my projects have retrocompatiilty to 3.0 (any news about App Store unsupporting?) so I can't use it. But now I'm working in a new project with base deployment in iOS 5 so I'm using ARC.
My question is so simple. I'm used to declare private instance variables and public properties. For example:
#interface MyClass : NSObject {
#private
Var *aVar_;
Var *anotherVar_;
}
#property (nonatomic, readonly) Var *aVar;
#end
#implementation MyClass
#synthesize aVar = aVar_;
#end
Inside the class I work with instance variables, not properties.
But now I'm trying to avoid instance variables because I think there are not neccessary and redundant if I use proeprties, and I read time ago that is better to use properties instead of instance variable, but I'm not sure. That class now seems like that
#interface MyClass : NSObject
#property (nonatomic, readwrite, strong) Var *aVar;
#end
#interface MyClass()
#property (nonatomic, readwrite, strong) Var *anotherVar;
#end
#implementation MyClass
#synthesize aVar = aVar_;
#synthesize anotherVar = anotherVar_;
#end
In this case I'm still using instance variables (underscored) to manage my data because is less verbose and ARC takes into account all memory issues, but I don't know if that is correct.
Also I have another question. The property of aVar in the first chunk of code is readonly but if I use only properties I have to make that property readwrite. If I want to make the public property readonly, do I have to declare a public readonly property in the #interface and a private readwrite in private #interface?
Thank you so much.
The answer to your questions is somewhat complex, but generally you have the swing of it.
Since ARC does all the memory management for you, its often simpler to just use an ivar (private to the class, declared in the implementation) for your internal needs. In that case all usages just use the name.
With properties, you can as of Xcode 4.4 let Xcode synthesize the setter and getter, as well as the ivar. Auto-synthesized ivars are created with a leading "_" character.
You can define a property as readonly in the implementation, leave it as readonly, and set it in your code as '_foo = ....'. [Many on this site would consider this a bad practice, my point is you can do it.]
Xcode 4.4 has a warning titled "Implicit Synthesized Properties" with a default of NO. This creates a warning if you do not provide a #synthesize statement for each property, even though it will do the synthesis anyway.
Personally, I use ivars whenever I can, and only define properties when I need to either make something public to other classes, or I have categories declared in multiple files (in which case I put the interface declaration of the class extension in its own file along with properties defined in it.)
With the new Objective-C update you don't even need to synthesize the property. All you need to do is declare #property (strong, nonatomic) Var *aVar; and the compiler will automatically add the synthesizing, backing the self.aVar property with an _aVar instance variable.
If you declare a property, your implementation should generally use that property even though ARC reduces some of the memory management errors.
In init some prefer to avoid using properties because doing so might trigger KVO on an object (self) that is only partially initialized.
If I understand this correctly, copy enforces the setter to create a copy of the object passed in. However, if I use it together with readonly, there won't be a setter. So is my assumption correct, that combining #property (copy, readonly) doesn't make any sense or am I missing something?
It does make sense. For instance, if you want to access a property's setter in your implementation only:
#interface MyClass : NSObject
#property (nonatomic, copy, readonly) NSData *data;
- (id)initWithData:(NSData *)data;
#end
and in the class continuation in the .m file:
#interface MyClass ()
#property (nonatomic, copy, readwrite) NSData *data;
#end
Note that the copy, readonly declaration in the public header is required in this case!
According to Apple's documentation (which I've linked here for you):
copy
Specifies that a copy of the object should be used for assignment.
The previous value is sent a release message.
The copy is made by invoking the copy method. This attribute is valid
only for object types, which must implement the NSCopying protocol.
So yes, you're correct... readonly creates a getter method and copy would be effectively ignored, since there's no setter method that does assignment.
You are correct, it does not make sense to have both.
I think, if I saw such a property, on read, I would expect to receive a distinct returned object to the ivar unless the returned object was advertised to be immutable.
If I have
#property (readonly, copy) NSMutableArray* foo;
and I do this:
NSMutableArray* myFoo = [theObject foo];
[myFoo addObject: #"string"];
NSMutableArray* myOtherFoo = [theObject foo];
I would expect myOtherFoo not to have the extra string in it that myFoo has.
Note: I haven't verified this yet.
I have checked it now and my expectation is incorrect. I think I would regard that as a bug.
As someone that's new to Objective-C can someone give me an overview of the retain, assign, copy and any others I'm missing, that follow the #property directive? What are they doing and why would I want to use one over another?
Before you know about the attributes of #property, you should know what is the use of #property.
#property offers a way to define the information that a class is intended to encapsulate.
If you declare an object/variable using #property, then that object/variable will be accessible to other classes importing its class.
If you declare an object using #property in the header file, then you have to synthesize it using #synthesize in the implementation file. This makes the object KVC compliant. By default, compiler will synthesize accessor methods for this object.
accessor methods are : setter and getter.
Example:
.h
#interface XYZClass : NSObject
#property (nonatomic, retain) NSString *name;
#end
.m
#implementation XYZClass
#synthesize name;
#end
Now the compiler will synthesize accessor methods for name.
XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:#"liza"]; // first letter of 'name' becomes capital in setter method
List of attributes of #property
atomic, nonatomic, retain, copy, readonly, readwrite, assign, strong, getter=method, setter=method, unsafe_unretained
atomic is the default behavior. If an object is declared as atomic then it becomes thread-safe. Thread-safe means, at a time only one thread of a particular instance of that class can have the control over that object.
If the thread is performing getter method then other thread cannot perform setter method on that object. It is slow.
#property NSString *name; //by default atomic`
#property (atomic)NSString *name; // explicitly declared atomic`
nonatomic is not thread-safe. You can use the nonatomic property attribute to specify that synthesized accessors simply set or return a value directly, with no guarantees about what happens if that same value is accessed simultaneously from different threads.
For this reason, it’s faster to access a nonatomic property than an atomic one.
#property (nonatomic)NSString *name;
retain is required when the attribute is a pointer to an object.
The setter method will increase retain count of the object, so that it will occupy memory in autorelease pool.
#property (retain)NSString *name;
copy If you use copy, you can't use retain. Using copy instance of the class will contain its own copy.
Even if a mutable string is set and subsequently changed, the instance captures whatever value it has at the time it is set. No setter and getter methods will be synthesized.
#property (copy) NSString *name;
now,
NSMutableString *nameString = [NSMutableString stringWithString:#"Liza"];
xyzObj.name = nameString;
[nameString appendString:#"Pizza"];
name will remain unaffected.
readonly If you don't want to allow the property to be changed via setter method, you can declare the property readonly.
Compiler will generate a getter, but not a setter.
#property (readonly) NSString *name;
readwrite is the default behavior. You don't need to specify readwrite attribute explicitly.
It is opposite of readonly.
#property (readwrite) NSString *name;
assign will generate a setter which assigns the value to the instance variable directly, rather than copying or retaining it. This is best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates.
Keep in mind retain and assign are basically interchangeable when garbage collection is enabled.
#property (assign) NSInteger year;
strong is a replacement for retain.
It comes with ARC.
#property (nonatomic, strong) AVPlayer *player;
getter=method If you want to use a different name for a getter method, it’s possible to specify a custom name by adding attributes to the property.
In the case of Boolean properties (properties that have a YES or NO value), it’s customary for the getter method to start with the word “is”
#property (getter=isFinished) BOOL finished;
setter=method If you want to use a different name for a setter method, it’s possible to specify a custom name by adding attributes to the property.
The method should end with a colon.
#property(setter = boolBool:) BOOL finished;
unsafe_unretained There are a few classes in Cocoa and Cocoa Touch that don’t yet support weak references, which means you can’t declare a weak property or weak local variable to keep track of them. These classes include NSTextView, NSFont and NSColorSpace,etc. If you need to use a weak reference to one of these classes, you must use an unsafe reference.
An unsafe reference is similar to a weak reference in that it doesn’t keep its related object alive, but it won’t be set to nil if the destination object is deallocated.
#property (unsafe_unretained) NSObject *unsafeProperty;
If you need to specify multiple attributes, simply include them as a comma-separated list, like this:
#property (readonly, getter=isFinished) BOOL finished;
The article linked to by MrMage is no longer working. So, here is what I've learned in my (very) short time coding in Objective-C:
nonatomic vs. atomic
- "atomic" is the default. Always use "nonatomic". I don't know why, but the book I read said there is "rarely a reason" to use "atomic". (BTW: The book I read is the BNR "iOS Programming" book.)
readwrite vs. readonly
- "readwrite" is the default. When you #synthesize, both a getter and a setter will be created for you. If you use "readonly", no setter will be created. Use it for a value you don't want to ever change after the instantiation of the object.
retain vs. copy vs. assign
"assign" is the default. In the setter that is created by #synthesize, the value will simply be assigned to the attribute. My understanding is that "assign" should be used for non-pointer attributes.
"retain" is needed when the attribute is a pointer to an object. The setter generated by #synthesize will retain (aka add a retain count) the object. You will need to release the object when you are finished with it.
"copy" is needed when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
After reading many articles 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
Below is a link to the detailed article where you can find these attributes.
Many thanks to all the people who give best answers here!!
Variable property attributes or Modifiers in iOS
Here is the Sample Description from Article
atomic
-Atomic means only one thread access the variable(static type).
-Atomic is thread safe.
-but it is slow in performance
-atomic is default behavior
-Atomic accessors in a non garbage collected environment (i.e. when using retain/release/autorelease) will use a lock to
ensure that another thread doesn't interfere with the correct setting/getting of the value.
-it is not actually a keyword.
Example :
#property (retain) NSString *name;
#synthesize name;
nonatomic
-Nonatomic means multiple thread access the variable(dynamic type).
-Nonatomic is thread unsafe.
-but it is fast in performance
-Nonatomic is NOT default behavior,we need to add nonatomic keyword in property attribute.
-it may result in unexpected behavior, when two different process (threads) access the same variable at the same time.
Example:
#property (nonatomic, retain) NSString *name;
#synthesize name;
Explain:
Suppose there is an atomic string property called "name", and if you call [self setName:#"A"] from thread A,
call [self setName:#"B"] from thread B, and call [self name] from thread C, then all operation on different thread will be performed serially which means if one thread is executing setter or getter, then other threads will wait. This makes property "name" read/write safe but if another thread D calls [name release] simultaneously then this operation might produce a crash because there is no setter/getter call involved here. Which means an object is read/write safe (ATOMIC) but not thread safe as another threads can simultaneously send any type of messages to the object. Developer should ensure thread safety for such objects.
If the property "name" was nonatomic, then all threads in above example - A,B, C and D will execute simultaneously producing any unpredictable result. In case of atomic, Either one of A, B or C will execute first but D can still execute in parallel.
strong (iOS4 = retain )
-it says "keep this in the heap until I don't point to it anymore"
-in other words " I'am the owner, you cannot dealloc this before aim fine with that same as retain"
-You use strong only if you need to retain the object.
-By default all instance variables and local variables are strong pointers.
-We generally use strong for UIViewControllers (UI item's parents)
-strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.
Example:
#property (strong, nonatomic) ViewController *viewController;
#synthesize viewController;
weak (iOS4 = unsafe_unretained )
-it says "keep this as long as someone else points to it strongly"
-the same thing as assign, no retain or release
-A "weak" reference is a reference that you do not retain.
-We generally use weak for IBOutlets (UIViewController's Childs).This works because the child object only
needs to exist as long as the parent object does.
-a weak reference is a reference that does not protect the referenced object from collection by a garbage collector.
-Weak is essentially assign, a unretained property. Except the when the object is deallocated the weak pointer is automatically set to nil
Example :
#property (weak, nonatomic) IBOutlet UIButton *myButton;
#synthesize myButton;
Strong & Weak Explanation, Thanks to BJ Homer:
Imagine our object is a dog, and that the dog wants to run away (be deallocated).
Strong pointers are like a leash on the dog. As long as you have the leash attached to the dog, the dog will not run away. If five people attach their leash to one dog, (five strong pointers to one object), then the dog will not run away until all five leashes are detached.
Weak pointers, on the other hand, are like little kids pointing at the dog and saying "Look! A dog!" As long as the dog is still on the leash, the little kids can still see the dog, and they'll still point to it. As soon as all the leashes are detached, though, the dog runs away no matter how many little kids are pointing to it.
As soon as the last strong pointer (leash) no longer points to an object, the object will be deallocated, and all weak pointers will be zeroed out.
When we use weak?
The only time you would want to use weak, is if you wanted to avoid retain cycles
(e.g. the parent retains the child and the child retains the parent so neither is ever released).
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;
unsafe_unretained
-unsafe_unretained is an ownership qualifier that tells ARC how to insert retain/release calls
-unsafe_unretained is the ARC version of assign.
Example:
#property (nonatomic, unsafe_unretained) NSString *nickName;
#synthesize nickName;
copy
-copy is required when the object is mutable.
-copy specifies the new value should be sent -copy on assignment and the old value sent -release.
-copy is like retain returns an object which you must explicitly release (e.g., in dealloc) in non-garbage collected environments.
-if you use copy then you still need to release that in dealloc.
-Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other
owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
Example:
#property (nonatomic, copy) NSArray *myArray;
#synthesize myArray;
Atomic property can be accessed by only one thread at a time. It is thread safe. Default is atomic .Please note that there is no keyword atomic
Nonatomic means multiple thread can access the item .It is thread unsafe
So one should be very careful while using atomic .As it affect the performance of your code
prefer this links about properties in objective-c in iOS...
https://techguy1996.blogspot.com/2020/02/properties-in-objective-c-ios.html