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.
Related
When I control-drag outlet from xib, I got unsafe_unretained property by default. I'm using Xcode 9.1. The following code is what it looks like.
#property (unsafe_unretained, nonatomic) IBOutlet UILabel *shIndexLabel;
__unsafe_unretained specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong
references to the object. If the object it references is deallocated,
the pointer is left dangling.
Above excerpt from Apple docs. So answering your question WHY?
It is not possible for the Swift compiler to know if these references
are really intended to be strong (+1) or unretained (+0)
This change involved with respect to the swift compiler. They made __unsafe_unretained by default.
Actually, it's a bug of Xcode. It seems unsafe_unretained will appear when project didn't complete indexing. So we should change it to weak manually.
I am little confused about specifying strong, copy, or assign and not specifying them. We don't use NIB files. My colleague always use following - he says iOS detects it and use it automatically strong, weak etc.
#interface viewController : UIViewController
#property (nonatomic) UIImageView *imageView1;
#property (nonatomic) NSUInteger num;
#property (nonatomic) NSArray *array;
#end
I prefer following way doing it.
#interface viewController : UIViewController
#property (nonatomic, strong) UIImageView *imageView1;
#property (nonatomic, assign) NSUInteger num;
#property (nonatomic, copy) NSArray *array;
#end
Which one is better programming style? First option always have strong type as it defaults but I always specifies them explicitly.
As pointed out in earlier answers, in Objective C properties are by default,
atomic, strong/retain, readwrite --> For pointer types
atomic, assign, readwrite --> For primitive types
Property types weak, copy need to be explicitly specified by the programmer and in no way gets automatically decided.
What does each mean,
strong/retain referenced objects are kept alive in the memory until specified.
weak referenced objects will be destroyed when there is no strong reference. Typically used to reference delegate objects.
copy will create a shallow copy of the object getting assigned to the property.
assign/usafe_unretained(ARC) assigns the value. If used in case of pointer types this is an unsafe unretained assignment of the pointer. In ARC, typically use weak for pointer types because it will make the ivar=nil once weak referenced object is destroyed. assign in this case will lead to dangling pointer.
Personally, I prefer specifying property types even if it strong by default. This adds readability, which comes handy specially when profiling application for memory leaks or debugging crashes.
You can read more about properties here.
Hope that helps.
With ARC, strong is the default so the two are technically the same. From the Transitioning to ARC Release Notes:
__strong is the default. An object remains “alive” as long as there is a strong pointer to it.
Note that ARC will NOT automatically detect when something needs to be weak, however.
I tend to be explicit, like your second example, but I think it's mostly a matter of style/habit.
The default for a property is strongand for a variable is __strong too. In your current example the recommended property would actually be weak, but strong is acceptable too.
For properties of non-primitives you should no longer use assign, but rather unsafe_unretained. Practically they're the same, but the latter lets you know that you're using an object unsafely.
The copy property means that an object is copied (using the copy method) and not retained. It's recommended for classes such as NSString and NSArray, which have mutable forms. This is because you don't want to retain what you think is an immutable string but is actually being changed elsewhere.
The assign property declaration should be used only for primitive types and structs, e.g. int and CGSize.
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
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.