I have to fix some existing code that builds just fine with LLVM (on iOS) so that it builds with llvm-gcc-4.2 too. I'm done with pretty much everything, except this pattern which is found at a few places:
#property (nonatomic, retain) __block id myProperty;
I suspect the intent here is to allow access to the property from inside a block without retaining self. How can I remove the __block attribute, which gcc doesn't support here, but still achieve the same effect?
I'll suggest you've found a compiler bug, the declaration:
#property (nonatomic, retain) __block id myProperty;
is meaningless. The __block qualifier is used on local (stack allocated) variables so they are passed by reference to blocks, so they can be updated, and are usually[*] stored on the heap rather than the stack.
Therefore the qualifier __block has no meaning on a property declaration which is concerned with object instances, which are heap allocated at all times in Obj-C.
Just drop the __block from the property declarations - for every compiler.
[*] If a block is never copied to the heap a compiler may optimize __block variables and not move those to the heap either.
just before you use the variable in a block, create a local pointer of type __block. Don't ever use __block in #property declarations.
EG: TypeOfVariable __block *bock_pointer = self.property;
^{ inside the block use bock_pointer }
Related
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
I am learning Objective-C and was just curious. I can create an object of a NSString in these places, and please provide any others. To me they all do the same thing. I don't know what is the difference is between them. Where is it stored? From where can I access it? What are the advantages?
1)
// .h
#interface ...
#property (strong,nonatomic) NSString *text;
#end
2)
// .h
#interface ... {
NSString *text
}
#end
3)
// .m
#interface ... ()
#property (strong,nonatomic) NSString *text;
#end
First and foremost, my answer is based on the latest Clang compiler, older versions worked slightly different.
So, you're not creating an object in neither. You're not even declaring an object in two of them.
In the first case, you're actually telling the compiler that you need to expose a property called text of type NSString. What the compiler does, is declaring an instance variable for you _text (which you can access without a problem by the way) and the methods needed to get and set that instance variable. As you can see the storage is still internal, you just have getters and setters set for you.
In the second case you're actually declaring an instance variable (ivar) yourself, just as the compiler does with _text. It's accustom to prefix it with _. The storage is still internal. On top of that, you can't access your ivar from outside, since it has no getter or setter and the implicit declaration is #private.
In the third case, you create an anonymous category (thus the empty parentheses) which adds a property to your class. Storage for this is a little bit harder/longer to explain, if you are curious about it, you can search up the Apple docs, see what a category is and so on. You can only access your property from within your class in this case, which makes it somehow redundant (the getters and setters), you could have declared it as an ivar.
You can also declare your ivars like this:
#interface GenericViewController : UIViewController{
NSString * text;
}
#end
#implementation GenericViewController{
NSString * text;
}
#end
Both of the above have local storage and private visibility (can't be accessed from outside). The difference between the two is that instance variables declared in the implementation are implicitly hidden and the visibility cannot be changed with #public, #protected and #private. If you use those directives you won't get compiler errors but are ignored.
I know that the #property generates the getters and setters in Objective-c. But I've seen some classes where they declare attributes with their respective #property and some times just the #property with no attributes and seams to work the same way. Whats the difference?
I know that the #property generates the getters and setters in Objective-c.
No you don't. #property declares a property which is a getter and optionally a setter (for read/write properties). The generation of the getter and setter is done by the #synthesize in the implementation (or by you writing the getter and setter).
But I've seen some classes where they declare attributes with their respective #property
Do you mean like this?
#interface Foo : NSObject
{
Bar* anAttribute; // <<=== this is an instance variable
}
#property (retain) Bar* anAttribute;
#end
In the modern Objective-C run time, if you #synthesize the property, you can leave out the instance variable declaration and the compiler will put it in for you. Whether you explicitly declare the instance variable or not is a matter of personal preference.
Just to confuse you a bit, in the very latest compiler, you can omit the #synthesize and the compiler will put it in for you as long as you haven't explicitly created a getter or setter.
Under ios 5.0, there are ten different attributes you can attach to a property declaration: nonatomic, readwrite, readonly, getter=name, setter=name, strong, retain, copy, weak, assign. (strong, weak are new under ios 5.0 and are only meaningful if you use ARC).
nonatomic declares that variable access should not be protected against multithreaded concurrent access. This isn't the default, although 99% of the time it's what you want (since this protection makes your code run slower with no benefit if you're not doing multithreading).
readwrite/readonly should be fairly obvious - readwrite is the default, and if you declare a property readonly, it has no setter.
getter=, setter= control what the getter & setter methods should be called. If you omit them, they'll be called property name and set*property name*, respectively.
The remaining attributes (strong, weak, retain, copy, assign) are hints to the memory manager, and their behavior varies depending on whether you're using ARC or not. If you're not, then the "retain" property tells the setter method to automatically call retain on any object that it gets a reference to. This means that you must also call release in the deallocator.
The "assign" property tells the setter not to call retain - so if the object is released by another object, this pointer could be left dangling.
The "copy" property tells the setter to call retain and also to make a copy of the property - this is useful when you get, say, an NSDictionary and you don't want the caller to pass an instance of NSMutableDictionary and change the contents out from underneath you.
If you're using ARC, you'll normally only set "strong" or "weak". (strong is a synonym for retain, so they can be used interchangeably). "strong" tells ARC to retain the variable for you - "weak" tells it not to. "weak" is useful when you have a potential "retain cycle" where object A refers to object B and object A - if they both retain each other, you have a memory leak, so you'll want to make one of them a weak reference.
There is a conceptual overview of Blocks objects in objective-c within this Apple reference:
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Blocks.pdf
However, it does not really explain two topics that concern me and may concern other people. The first question is like that: can I assign a nil to a Block reference? Or should I use NULL? Or can I use neither of them?
The second problem lies in the sphere of memory management. Say, I have declared such a method creating a block object on the stack.
-(void)makeTheClass
{
TheClass *object = [[TheClass alloc] init];
object.blockReference = ^(void) { return nil; }
}
This object, being created within some scope, is going to be destroyed after it goes out of it. But TheClass object is actually going to store a reference to this (nearly destroyed) Block:
typedef id (^WeirdBlockType)(void);
#interface TheClass {
WeirdBlockType blockReference;
}
How do I declare a class property for such a block?
What's the difference between these two:
#property (nonatomic, retain) WeirdBlockType blockReference;
#property (nonatomic, copy) WeirdBlockType blockReference;
?
It is clearly said in the Apple documentation that block copying moves the block to the heap. But what if I just retain it? Is it going to be destroyed after it goes out of makeTheClass method scope?
Well I've found the solution.
Thanks to Gojan for his answer, but he was actually wrong in one place:
Wevah was right. Retain on a block has no effect until it is completely moved to the heap, and only Block_copy accomplishes such a task.
Perhaps blocks are not the only objects that cannot be retained while they are on the stack; but whilst you create (alloc and init) any NSObject subclass instances on the heap by default, you don't care about it - retain works as usual. Block objects are created on the stack by default, that's why the work a little unexpectedly.
Thanks everybody!
can I assign a nil to a Block
reference? Or should I use NULL?
nil can be read as "an empty id type" and NULL is defined like ((void *)0). The difference here is the context. If you are working with NSObject's based objects you should use nil.
In the case of blocks you should use nil because you can interact with the block like if it was an NSObject (you can retain it, release it, etc). But if you use NULL it should work.
How do I declare a class property for
such a block? What's the difference
between these two:
#property (nonatomic, retain) WeirdBlockType blockReference;
#property (nonatomic, copy) WeirdBlockType blockReference;
?
In the documentation says:
If you are using Objective-C, you can
send a block copy, retain, and release
(and autorelease) messages.
So both declarations are valid, but if you ask my I prefer retain than copy.
In conclusion:
Blocks are treated like objects defined and instantiated at the same time (runtime) so after you get a perdurable reference to it you can think that reference like any other object.
Do properties in Objective-C 2.0 require a corresponding instance variable to be declared? For example, I'm used to doing something like this:
MyObject.h
#interface MyObject : NSObject {
NSString *name;
}
#property (nonatomic, retain) NSString *name;
#end
MyObject.m
#implementation
#synthesize name;
#end
However, what if I did this instead:
MyObject.h
#interface MyObject : NSObject {
}
#property (nonatomic, retain) NSString *name;
#end
Is this still valid? And is it in any way different to my previous example?
If you are using the Modern Objective-C Runtime (that's either iOS 3.x or greater, or 64-bit Snow Leopard or greater) then you do not need to define ivars for your properties in cases like this.
When you #synthesize the property, the ivar will in effect be synthesized also for you. This gets around the "fragile-ivar" scenario. You can read more about it on Cocoa with Love
In your interface, you can formally declare an instance variable between the braces, or via #property outside the braces, or both. Either way, they become attributes of the class. The difference is that if you declare #property, then you can implement using #synthesize, which auto-codes your getter/setter for you. The auto-coder setter initializes integers and floats to zero, for example. IF you declare an instance variable, and DO NOT specify a corresponding #property, then you cannot use #synthesize and must write your own getter/setter.
You can always override the auto-coded getter/setter by specifying your own. This is commonly done with the managedObjectContext property which is lazily loaded. Thus, you declare your managedObjectContext as a property, but then also write a -(NSManagedObjectContext *)managedObjectContext method. Recall that a method, which has the same name as an instance variable/property is the "getter" method.
The #property declaration method also allows you other options, such as retain and readonly, which the instance variable declaration method does not. Basically, ivar is the old way, and #property extends it and makes it fancier/easier. You can refer to either using the self. prefix, or not, it doesn't matter as long as the name is unique to that class. Otherwise, if your superclass has the same name of a property as you, then you have to say either like self.name or super.name in order to specify which name you are talking about.
Thus, you will see fewer and fewer people declare ivars between the braces, and instead shift toward just specifying #property, and then doing #synthesize. You cannot do #synthesize in your implementation without a corresponding #property. The Synthesizer only knows what type of attribute it is from the #property specification. The synthesize statement also allows you to rename properties, so that you can refer to a property by one name (shorthand) inside your code, but outside in the .h file use the full name. However, with the really cool autocomplete that XCode now has, this is less of an advantage, but is still there.
Hope this helps clear up all the confusion and misinformation that is floating around out there.
it works both ways but if you don't declare them in the curly braces, you won't see their values in the debugger in xcode.
From the documentation:
In general the behavior of properties is identical on both modern and legacy runtimes (see “Runtime Versions and Platforms” in Objective-C Runtime Programming Guide). There is one key difference: the modern runtime supports instance variable synthesis whereas the legacy runtime does not.
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.
If you are using XCode 4.4 or later it will generate instance variable synthesizing code for you.
You just have to declare properties like below; it will generate synthesizing code and instance variable declaring code for you.
#property (nonatomic, strong) NSString *name;
it will generate synthesizing code as
#synthesize name = _name;
and you can access instance variable using _name
it is similar to declare
NSString* _name
but if you declare read-only property it like
#property (nonatomic, strong, readonly) NSString *name;
it will generate code
#synthesize name;
or
#synthesize name = name;
So you should access instant variable name with out prefix "_"
any way you can write your own synthesizing code then compiler will generate code for you.
you can write
#synthesize name = _name;
The Objective-C Programming Language: Property Implementation Directives
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.