What is the difference between these two declarations in Objective-C?
I have been looking at some Apple source code example and they used the second one in various circumstances. I just wanted to understand why and when is best to use the second version rather than the first one (I know the difference between strong, weak, atomic, nonatomic).
#property(nonatomic, strong) NSObject * myObject;
// vs
#property NSObject * myObject2; //No additional qualifiers
#property NSObject * myObject2
// is same as
#property (atomic,strong) NSObject * myObject2
which one to use, is developer's personal choice
Related
My understanding so far is that (retain) increases the reference count of a property and is essentially the exact same as (strong). Since all properties are set to retain by default (unless specified otherwise), is adding (strong) needed at all:
#property(nonatomic, strong) NSString *name;
Is the same as:
#property(nonatomic) NSString *name;
Both the above are the same, right?
Since ARC was introduced, "strong", "atomic", and "readwrite" are set by default.
These properties are equivalent:
#property NSArray *name;
#property (strong, atomic, readwrite) NSArray *name;
Source: http://useyourloaf.com/blog/default-property-attributes-with-arc.html
From the documentation:
By default, both Objective-C properties and variables maintain strong
references to their objects.
So both forms are the same.
Can I replace an property with new one using some obj-c runtime features.
So I have a class A which contains a property:
#property (nonatomic, strong) Status *status;
So I want to inherit from this class like ClassB : ClassA and have ability to switch original #property (nonatomic, strong) Status *status; to my new property like #property (nonatomic, assign) NSInteger status;
So the reasone why I needed because I don't want to have a full copy of class A which contains 20 properties, so I just want to inherit from it and replace one with needed type.
Not sure if this possible, but I know something like swizzling and some obj-c runtime features can make a magic in the code.
This question already has answers here:
What is the difference between ivars and properties in Objective-C
(2 answers)
Closed 8 years ago.
What is the difference between:
#interface PhotoAppViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
UIImageView * imageView;
UIButton * choosePhotoBtn;
UIButton * takePhotoBtn;
}
#property (nonatomic, retain) IBOutlet UIImageView * imageView;
#property (nonatomic, retain) IBOutlet UIButton * choosePhotoBtn;
#property (nonatomic, retain) IBOutlet UIButton * takePhotoBtn;
And this:
#interface PhotoAppViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property (nonatomic, retain) IBOutlet UIImageView * imageView;
#property (nonatomic, retain) IBOutlet UIButton * choosePhotoBtn;
#property (nonatomic, retain) IBOutlet UIButton * takePhotoBtn;
What do the curly braces mean after the delegation?
From http://rypress.com/tutorials/objective-c/properties.html:
An object’s properties let other objects inspect or change its state.
But, in a well-designed object-oriented program, it’s not possible to
directly access the internal state of an object. Instead, accessor
methods (getters and setters) are used as an abstraction for
interacting with the object’s underlying data.
Stackoverflow Answer
The "curly braces" are the scope in which instance variables, (also known as ivars) are defined. Properties are variables that can be publicly accessed (i.e. by other classes), whereas instance variables are private and can be only accessed in the scope of the class's implementation itself.
Read this and this to get an intuitive understanding about the differences between properties and ivars.
I'd strongly recommend reading Apple's documentation on Objective-C, or a good book on the same topic if the former turns out to a tad bit too technical for your taste.
So here's my dilemma. I'm dealing with legacy code and trying to simplify and reduce a huge amount of redundancy in the code base. Here's the crux of the matter. I'm trying to consolidate two very similar classes into a superclass/subclass relationship. One is a subclass of NSObject the other a subclass of NSManagedObject.
I have a class that contains only variables called InventoryItems.h. It is a subclass of NSObject.
#property (nonatomic, retain) NSString * desc;
#property (nonatomic, retain) NSString * locationInventoryId;
...
InventoryItems.m
#synthesize desc;
#synthesize locationInventoryId;
...
There is another class that is called FavoriteInventoryItems.h that is a subclass of NSManagedObject.
It contains exactly the same variables as InventoryItems with one additional variable.
FavoriteInventoryItems.h
#property (nonatomic, strong) NSString * desc;
#property (nonatomic, strong) NSString * locationInventoryId;
#property (nonatomic, strong) NSString * dateAddedAsFav;
....
FavoriteInventoryItems.m
#dynamic desc;
#dynamic locationInventoryId;
#dynamic dateAddedAsFav;
...
I can successfully make things work by making InventoryItems a subclass of NSManagedObject and then making FavoriteInventoryItems a subclass of InventoryItems. It does work but I get a message indicating the following:
CoreData: error: Failed to call designated initializer on NSManagedObject class 'InventoryItems'
My solution assuredly is a hack that may have negative consequences.
There are multiple places where the code resembles something like the following:
if (InventoryItem)
...many lines of code here
else if(FavoriteInventoryItem)
...exact same code as above based on favorites
I'm not sure how else to consolidate both of these class into superclass/subclass relationship. Or is there a better way to handle this problem that doesn't involve inheritance? Any ideas?
Try to use a protocol to specify what is common between the classes and allow the 'using' code to be generic to the protocol.
The specification of a protocol is the important part, the implementation already exists in the 2 classes you have. The specification would list the common methods (or properties) between the 2 classes. Then, in the duplicated code, instead of saying:
InventoryItem *item = ...
or
FavoriteInventoryItem *item = ...
You would say:
id < InventoryItem > item = ...
I'm duplicating names because I can't know what a better name is, but the protocol is defined as:
#protocol InventoryItem < NSObject >
#property (nonatomic, strong) NSString * desc;
#property (nonatomic, strong) NSString * locationInventoryId;
#end
Then the code using the protocol doesn't care about what the underlying class is, it just cares what the protocol offers:
item.desc = #"Teddies";
item.locationInventoryId = ...
Sorry if this is stupid... but it confuses me?...
I'm trying a new storyboard app with Xcode and just asked myself why there is a second declaration of the #interface in my implementation file?
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
}
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
....
#end
See Apple's documentation: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html
It's a class extension, subtly different from a category, since it has no name inside the parentheses. You use it for declaring properties and methods that are intended to be kept private (out of the header), and redeclaring publicly read-only properties and methods as privately read-write. This allows for cleaner encapsulation.
By request, a friendly example:
JYDuckPondManager.h
#interface JYDuckPondManager : NSObject
#property (nonatomic, assign, readonly) NSUInteger duckCount;
#property (nonatomic, assign, readonly) CGFloat waterLevel;
- (JYDuckReaction *)feedDucks:(JYDuckFood *)food;
- (JYDuckReaction *)harassDucks:(JYDuckTaunt *)taunt;
#end
JYDuckPondManager.m (extension, imaginary implementation omitted)
#interface JYDuckPondManager ()
//// Redefined for internal modification
#property (nonatomic, assign, readwrite) NSUInteger duckCount;
#property (nonatomic, assign, readwrite) CGFloat waterLevel;
//// Internally exclusive properties
#property (nonatomic, strong) NSSet *duckPersonalitySet;
#property (nonatomic, assign) CGFloat flockAnxietyLevel;
//// Private messages
- (void)recalculatePondState;
#end
Other objects should be able to interact with the pond, but they're not supposed to know certain things going on in the pond or redefine the pond's statistics. Keeping nuts-and-bolts stuff in the .m extension ensures that the .h is concise and appropriately limited.
The second #interface block in the .m file is an extension. You could add declarations for methods and instance variables you want to use internally within your class.
The second interface #interface ViewController () is a class extension which is like an anonymous category. A class extension is declared like a category only without a name. Declarations found in these extensions directly extend the declarations found in the class’s primary #interface and can sometimes (in some situations) override declarations found in the primary interface.