Regarding #property and #synthesize [duplicate] - iphone

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
#property #synthesize
Hi i found in so many apps after creating the #property we have to declare #synthsize also but i would like to know the difference between
NSArray *_failedBankInfos;
#property (nonatomic, retain) NSArray *failedBankInfos;
#synthesize failedBankInfos = _failedBankInfos;
and
#property (nonatomic, retain) NSArray *_failedBankInfos;
#synthesize _failedBankInfos;
can anyone explain this please.

#synthesize will map the property with the declaration of the iVar i.e. will create the getter and setter methods without needing the developer to implement the accessor methods explicitly and the memory management in them(as per the parameters inside the #property eg: retain, copy.).
So, when we use the *_iVar(which is supposed to be a private iVar as per the naming conventions) and we want to have the accessor methods look like the ones without the "_" eg: [aClass getIVar] and not [aClass get_iVar] we map the _iVar with the #synthesize iVar=_iVar to the property #property(retain/copy/assign,atomic/nonatomic) NSObject *iVar;
PS: Also refer the Automatic Reference Count in iOS>=5.0 at Ray's

Related

Obj-C #synthesize [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Prefixing property names with an underscore in Objective C
iPhone App Developer Beginner here:
in .h
#property (nonatomic, retain) IBOutlet UILabel *detailDescriptionLabel;
in .m
#synthesize detailDescriptionLabel = _detailDescriptionLabel;
I'm used to seeing
#synthesize detailDescriptionLabel;
the = _ is throwing me off, what is this doing?
Each property is backed by an instance variable. The language allows for them to be named differently. By doing #synthesize detailDescriptionLabel = _detailDescriptionLabel;, you're basically saying that use _detailDescriptionLabel as the backing instance variable for the property detailDescriptionLabel. If you just do #synthesize detailDescriptionLabel;, it implicitly understands that the instance variable has the same name.
n .h
UILabel *_detailDescriptionLabel;
}
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
in .m
#synthesize detailDescriptionLabel = _detailDescriptionLabel;
This line means that the property "detailDescriptionLabel" will have a setter and getter for the class attribute named "_detailDescriptionLabel"
If the name was the same, you will have
#synthesize detailDescriptionLabel;

MKAnnotation - adding url

I'm working through mayurbirari's sample code to generate a mapkit view, I want to add a url to the popup. I've tried to understand the apple reference to subclass but TBH it just isnt going it.
I need to create a subclass that can have additional variable added to it as MKANNOTATION is core file and cannot be changed - therefore how do I do it?? I'm confused about how to set it up.
the code can be found here --> http://mayurbirari.wordpress.com/2011/02/07/how-to-access-mkmapkit-in-iphone/
if someone could show me the example of the subclass with URL added to it, it would probably sink in, but all the examples I've found seem to be over complicated.
MKAnnotation is a protocol that you have to adopt in your own class -- whichever class you're using to represent an annotation object. This is often a class that's part of your data model. For example, you might have a Person class and want to show instances of Person on a map. You'd adopt MKAnnotation in Person. It's easy to use properties for this:
#interface Person : NSObject <MKAnnotation>
{
//...
}
//...
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSString *subtitle;
#end
And then implement the methods from MKAnnotation in your class:
#implementation Person
#synthesize coordinate;
#synthesize title;
#synthesize subtitle;
//...various methods of Person...
#end
Now you can add instances of Person to the map as annotations.

When declaring class properties/variables, can you just declare it via #property?

I've noticed that some generated classes only declare class properties/variables via #property, and don't include them within the #interface, as such:
#interface AddItemViewController : UITableViewController {
}
#property (nonatomic, retain) UITextField *itemName;
I was just curious if that's an acceptable way to do it, or if that is done for different reasons?
I normally do this:
#interface AddItemViewController : UITableViewController {
UITextField *itemName;
}
#property (nonatomic, retain) UITextField *itemName;
I declare it first in the #interface and then add the #property for it...
* Update *
I just wanted to update this a bit, because it's still not 100% clear to me.
I always thought that to declare a #property, you first needed to declare it within the #interface first, and then I saw this:
#interface mInventoryAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#end
All of those #property declarations are declared only as #properties, and not within the #interface.
For example, if I had say NSString *myString - I can declare that in the #interface and not as a #property and still have access to it no problem, but the getters and setters won't be created. I could also declare it in both. But what if I just declare it as #property, as such:
#interface AddItemViewController : UITableViewController {
}
#property (nonatomic, retain) NSString *myString;
Notice how I didn't add it between the #interface { } - how does it differ.
Sorry for repeating, but I'm just trying to reword this so that I can get an answer that makes more sense to me.
With the "modern" runtime, which the iPhone uses, the compilers can create the instance variable for you. Just use:
#synthesize itemName;
or if you prefer...
#synthesize itemName=_itemName;
...in your implementation. The compilers will then create ivar 'itemName' or '_itemName'.
This is of course for the case that the property is a simple getter/setter for one particular instance variable.
EDIT: NVM, per #bbum, what I thought of in my mind as the "32-bit" sim is actually the older simulator that didn't behave like the new runtime. The newer simulator is still 32-bit, and supports this behavior. See his comment below.
update
In response to your updated question:
The "interface" for a class is everything up to the #end. I think what you are calling "interface" is actually just the instance variables within the {}. What is between the {} are the instance variables for your class. The whole #interface includes those instance variables PLUS the method and #property declarations between the {} and the #end.
So I think what you are really asking is if you have a #property in your #interface, and that #property is just a simple getter/setter pair, then do you need to declare a "backing" instance variable also in your #interface, within the {}.
The answer for iPhone is NO. The compilers (both) can create that instance variable for you.
I hope that answers the question?
It is perfectly acceptable to do it this way. You would however need to implement the setter/getter methods yourself. These can not be created using the #synthesize syntax.
One reason to use this approach could be to have the properties based on something more complex than just setting and getting a value. It doesn't however make much sense for simple Nib connections as in your example.

General Programming Question about properties, assign, retain, and declarations

I was going through the AVCam project from WWDC and I'm curious about the following code. I thought you were supposed to declare an object, then #property (nonatomic,retain), then synthesize.
The Demo code does it a little differently, I'll post some code (just a sample), anyone know what this does and when you should use it? Can anyone explain its significance and when to use it?
#interface AVCamCaptureManager : NSObject {
#private
// Capture Session
AVCaptureSession *_session;
AVCaptureVideoOrientation _orientation;
// Identifiers for connect/disconnect notifications
id _deviceConnectedObserver;
id _deviceDisconnectedObserver;
}
#property (nonatomic,readonly,retain) AVCaptureSession *session;
#property (nonatomic,assign) AVCaptureVideoOrientation orientation;
#property (nonatomic,readonly,retain) AVCaptureAudioChannel *audioChannel;
#property (nonatomic,assign) NSString *sessionPreset;
in the implementation file:
#interface AVCamCaptureManager ()
#property (nonatomic,retain) AVCaptureSession *session;
#property (nonatomic,retain) AVCaptureDeviceInput *videoInput;
#property (nonatomic,retain) AVCaptureDeviceInput *audioInput;
#end
#implementation AVCamCaptureManager
#synthesize session = _session;
#synthesize orientation = _orientation;
#dynamic audioChannel;
#dynamic sessionPreset;
#dynamic focusMode;
- (id) init
{
#property (nonatomic,readonly,retain) AVCaptureSession *session;
This is a property that is readonly externally. Internally, it will have a setter that retains the new value.
#property (nonatomic,assign) AVCaptureVideoOrientation orientation;
This is a property that does a simple assignment to store the new value (since you can't -copy or -retain primitives).
#property (nonatomic,readonly,retain) AVCaptureAudioChannel *audioChannel;
This is a property that is readonly externally. Internally, it will have a setter that retains the new value.
#property (nonatomic,assign) NSString *sessionPreset;
This is a property that does a simple assignment to store the new string value. This is normally not a good idea, unless you're only allowing pre-defined constants for the presets. When dealing with NSString properties, you generally want them to be copy unless you have a good reason against it.
In the implementation file:
#property (nonatomic,retain) AVCaptureSession *session;
#property (nonatomic,retain) AVCaptureDeviceInput *videoInput;
#property (nonatomic,retain) AVCaptureDeviceInput *audioInput;
These are used in conjunction with the properties declared in the header, except now it's readwrite. By declaring the version in the header as readonly, anyone using the class will not have access to the setSession: method. We re-declare this property internally so that we can have access to the setter (and the setter retains the new value). Also, if the property is not present in the header, the user won't know it exists, but we'll still be able to use it internally.
#synthesize session = _session;
#synthesize orientation = _orientation;
This means you want the compiler to generate the appropriate setters and getters for the session and orientation properties, and that you want those properties to store their values in the _session and _orientation instance variables, respectively.
#dynamic audioChannel;
#dynamic sessionPreset;
#dynamic focusMode;
This means that the implementations for the setters and getters will be provided at runtime. You usually don't use #dynamic properties yourself, other than the ones provided by the Core Data framework.
In this code, the session property is defined as readonly outside of the class and readwrite inside the class. By overriding the session property in an unnamed category before synthesizing it, a set accessor will also be synthesized, but the header file says it is readonly so other classes don't know about the set accessor. The category also defines two new properties which are not visible to other classes at all.
The retain and assign keywords tell the compiler how the accessor methods should work. Retain means that the set accessor should retain the value of the property, and the assign keyword tells it to set the property without retaining it. There is also copy, which copies the value and is often used to make sure a mutable value isn't set. The default is assign, but the compiler will issue a warning if nothing is specified for an object property.
Can you explain what you're confused about here? My only guess is you are confused about audioChannel and sessionPreset, as they have no ivars and are declared #dynamic (there's also focusMode, but I don't even see a #property declaration for that in the code you pasted).
In any case, I expect that if you read the rest of the code you'll find that there are getters for -audioChannel and -sessionPreset that have been written, as well as a setter for -setSessionPreset:. Assuming that's the case, then the #dynamic declarations are completely unnecessary. #dynamic is only necessary to tell the compiler that the methods will exist at run-time; if they exist at compile-time then you don't need any directive whatsoever.

Apple SeismicXML Example App

In the SeismicXMLAppDelegate implementation file of this class they have the following code:
// forward declarations
#interface SeismicXMLAppDelegate ()
#property (nonatomic, retain) NSURLConnection *earthquakeFeedConnection;
#property (nonatomic, retain) NSMutableData *earthquakeData; // the data returned from the NSURLConnection
#property (nonatomic, retain) NSOperationQueue *parseQueue; // the queue that manages our NSOperation for parsing earthquake data
- (void)addEarthquakesToList:(NSArray *)earthquakes;
- (void)handleError:(NSError *)error;
#end
Why do they have a second interface in the implementation file?
http://developer.apple.com/library/ios/#samplecode/SeismicXML/Listings/Classes_SeismicXMLAppDelegate_m.html#//apple_ref/doc/uid/DTS40007323-Classes_SeismicXMLAppDelegate_m-DontLinkElementID_10
This is a called an Extension (or an anonymous Category) in Objective-C
You can add properties, change its attributes and declare new methods like in that example.
Why not doing it in the interface file?
Well there could be a lot of reasons, for design purposes, for not to exposing some properties., etc.
For example, you cannot call myAppDelegate.earthquakeData from RootViewController.m even if you #import "SeismicXMLAppDelegate.h".
You can only access to earthquakeDataproperty from inside of SeismicXMLAppDelegate class.
You can read more about Categories and Extensions here: The Objective-C Programming Language