I am have read up some tutorials on ARC and am still left a bit confused on properties declarations. I wrote most most my code using the following pattern:
#property (readwrite, nonatomic) PlayerData* playerData;
#property (readwrite, nonatomic) MusicLayer* musicLayer;
#property (readwrite, nonatomic) bool isPowerUpAvailable;
Now that I finally started to deal with memory leaks XCode suggested me that in some bits of code I should have added the "retain" keyword in the property declaration.
Using ARC I thought I shouldn't "Bother" about retain counts anymore. Is there some concept I am not getting or missing? Any tutorial references or explanation would be greatly appreciated.
ARC is will retain object based on the property declaration, you should use strong for properties that need to be retained and weak for properties that do not need to be retained.
weak properties are also nilled when the object is deallocated.
The compiler will always assume that properties are readwrite so there is no need to declare then this way.
#property (strong, nonatomic) PlayerData* playerData;
#property (strong, nonatomic) MusicLayer* musicLayer;
// Need use assign since strong is for objects only.
#property (assign, nonatomic) bool isPowerUpAvailable;
If you prefer continue to use your code, you can exclude ARC only on the specific file .m you want:
Go to Targets > Build Phases > Compile Sources and select your .m file double click on right column of the selection and add -fno-objc-arc so you are exclude ARC only a selected file.
Or if you want to convert all application to new code with ARC, after make a Backup of you project, go to:
Edit > Refactor > Convert to Objective-C ARC and after this do the same but click on Convert to modern Objective-C Sintax
here the screen:
Pay attention not always working before to try duplicate your project!
Hope this help you
Related
This question already has answers here:
What are the default attributes for Objective-C properties?
(3 answers)
Closed 7 years ago.
A #property can be set as strong, weak , assign , copy ... like
#property (copy, nonatomic) NSString *string;
#property (strong ,nonatomic) CustomClass *object;
#property (weak,nonatomic) id <CustomDelegate>delegate;
However, if
#property id <CustomDelegate>delegate; weak?strong?
#property (copy, nonatomic) NSString *string; strong?
If (weak,nonatomic) is abbreviated. What is the default value of an id? And other?
Properties Are Atomic by Default
This means that the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads.
Because the internal implementation and synchronization of atomic accessor methods is private, it’s not possible to combine a synthesized accessor with an accessor method that you implement yourself. You’ll get a compiler warning if you try, for example, to provide a custom setter for an atomic, readwrite property but leave the compiler to synthesize the getter.
For more detail you can read this article https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html
Thanks
id is a reference to some random Objective-C object of unknown class, thus it's default attributes are:
#property (atomic, readwrite, strong) id value;
Note: delegates 99.999% of the time should be weak.
I know that if I use
#interface TPN : UIViewController{
IBOutlet UIView *testView;
}
#property (strong, nonatomic) IBOutlet UIView *testView;
I know that the first one is essentially a private variable that is only accessed within the class. and the second one "#property" is able to be accessed from an instantiated object. I find it odd in most tutorials that people tend to set properties when they are usually changing an outlet from within the class itself. Is there any guideline I should be following?
You no longer need to specify the ivar at all. Nor is there a need to use #synthesize.
Use a property, but make sure it is weak, not strong
#interface TPN : UIViewController
#property (weak, nonatomic) IBOutlet UIView *testView;
In the implementation you can now access the ivar as _testView.
For a private property (above is public) instead put the #property within a category in the implementation file:
#import "TPN.h"
#interface TPN ()
#property (weak, nonatomic) IBOutlet UIView *testView;
#end
#implementation TPN
....
You are right. If you are only going to use the instance variable inside the class, there is no point to make it a property. A property simply means a pair of getter/setter. If you don't need to do anything specially when getting/setting, you can just use the instance variable directly.
Prior to ARC, there was a side benefit to using properties everywhere, in that it was easier to do memory management for object pointers -- properties declared as retain would automatically release and retain for you when you set it, without you typing that code yourself like you would have to do with an instance variable directly. However, now in ARC, the compiler does that for you anyway when you assign, if it's a strong instance variable. So this benefit is now irrelevant.
I would suspect that a lot of the reason people use properties for outlets is because of perpetuation of that usage in almost all tutorials and examples (possibly due to the previous benefit with retain memory management), and they simply don't realize they can do something different.
After converting project to ARC, The converting operation removed all the - assign, retain from the #properties decelerations, And left nonatomic only.
#property (nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;
#property (nonatomic) IBOutlet UIBarButtonItem *cameraToggleButton;
Even thogh "HE DID IT", xCode gives warnings on all the declarations in the project:
What is the problem?
And what should I do?
Thanks
Shani
The conversion did not go well even though XCode did it, it just failed to do so. What you have to do is basically make the properties that were declared as assign, declared as weak, and the ones that were declared as retain, now declared as strong.
This is however not always the case, which is why you should take a look at this Transitioning to ARC release notes before proceeding.
Hope that helps.
Like a doop I'd been declaring Instant Variables (iVar) and then #property in the interface .h file for a while now.
#interface MainGameViewController : UIViewController {
UserFactorsViewController *userFactorsViewController;
UITableView *myTableView;
}
#property (nonatomic, retain) UserFactorsViewController *userFactorsViewController;
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
Under Automatic Reference Counting, should I just dispense with iVar and go all #property? Should I even have the word "retain" in property? What if I'm deploying for iOS 4.3, should I still use ARC?
Don't feel like a doop, even though the compiler will add ivars for you if you don't include them, many people still declare them (many book authors as well) to make the code a little bit easier to read (easier to distinguish between ivar and property).
When creating a property now, Apple wants you to think in terms of Object Graphs, so do some research on "strong" and "weak" property attributes instead of retain and releases.
Also, iOS 4 is setup as a target for ARC so you should be ok. But I believe if you wanted to support iOS 3.0 you would have to manually manage retain and releases as before.
Objective-C for iPad, Where do you put IBOutlet? In instance variable declaration or #property declaration? Is there a difference at all?
IBOutlet can be a marker on ivars or a property declaration.
There is a slight difference. IBOutlet properties go through access methods whereas IBOutlet ivars are direct ivar access.
The major difference is that if the IBOutlet property is retained, you'll have to release it in -dealloc whereas you typically need not do anything with an IBOutlet ivar. The upside of IBOutlet property is that you get all the useful features of properties.
Both are valid, even if it's usually recommended to put it on a property.
The difference with a property is that it's available from the outside, and that getter/setter methods are used.
That also allows property qualifiers, like non-atomic and retain, usually set for the IBOutlets.
mmalc (who is definitely a reputable source) says that the current best-practice is putting it on the #property declaration. He gives details (along with some cavets) in his answer to this quiestion
Both are valid I suggest you to use #property
I do both, and synthesise it in the .m file. I'm not 100% that they're both essential, but it doesn't hurt.