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

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.

Related

Regarding #property and #synthesize [duplicate]

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

Forward declaring a protocol in objective-c

My class .h looks like:
#protocol AppInfoDelegate;
#class InfoTextView;
#interface AppInfoViewController : UIViewController <AppInfoDelegate> {
}
#property (nonatomic, retain) NSArray *textObjectsArray;
#property (nonatomic, retain) InfoTextView *itView;
#property (nonatomic, retain) UIButton *pgBackButton;
#property (nonatomic, retain) UIButton *pgFwdButton;
#end
#protocol AppInfoDelegate <NSObject>
- (void)closeButtonPressed:(id)sender;
#end
I get a warning that the protocol definition for AppInfoDelegate cannot be found. What is the proper way to do this and why cannot it not be found? Do I need to have the whole definition of the protocol before the interface? Thanks!
Using #protocol MyProtocol; is useful when you are asserting, for example, that a method will take id <MyProtocol> as an argument.
It is not useful when you are claiming that your class conforms to <MyProtocol>. The reason for this is that the compiler needs the full protocol declaration in order to verify that your class actually conforms to the protocol. (This compile-time check is one great reason to use formal protocols instead of the older informal ones.)
You can fix in two ways. One, as #skram suggests, is to just forward-declare the whole thing. This works, but it's also rather limited in my view. Why bother with a protocol in that case - just put everything in the class #interface and be done with it.
The second approach, which I prefer, is to actually have a separate header, such as MyProtocol.h. You can then freely import this into any header or implementation files as needed. This allows you to reuse a protocol easily (and avoid the headaches of circular imports that sometimes arise).
Try this:
#protocol AppInfoDelegate <NSObject>
- (void)closeButtonPressed:(id)sender;
#end
#class InfoTextView;
#interface AppInfoViewController : UIViewController <AppInfoDelegate> {
}
#property (nonatomic, retain) NSArray *textObjectsArray;
#property (nonatomic, retain) InfoTextView *itView;
#property (nonatomic, retain) UIButton *pgBackButton;
#property (nonatomic, retain) UIButton *pgFwdButton;
#end
Yes, superclass and adopted protocol definitions need to be defined (verbatim or by using #import) before the class definition. They cannot be forward-declared.
I've always seen the whole protocol definition before the #interface. I believe you can also put it into a separate file though

some confusions about " property" in Objective-C

#interface TheViewController : UIViewController
{
IBOutlet UITableView *table;
}
#property (nonatomic,retain) IBOutlet UITableView *table;
or just like this:
#interface TheViewController : UIViewController
{
}
#property (nonatomic,retain) IBOutlet UITableView *table;
Is it ok like the second one?
And what is the difference ?
And which is recommended ?
Is it ok like the second one?
The two syntaxes are correct, generally speaking.
And what is the difference ?
The second one will also declare the ivar for you, but will only work correctly newer Objective C runtime systems.
And which is recommended ?
good question... I think they are pretty equivalent, provided you can restrict yourself to the newer ObjC runtime systems. For more hints at possible downsides of not declaring ivars explicitly, please have a look at this S.O. post.
In Objective-C 2.0, synthesized properties will automatically create the corresponding ivars as required. So both syntaxes are correct..This article will make it clear for you..
These two are not quite equivalent even in the ObjC 2.0 environment because of the IBOutlet. That has to be declared on the property. They'd be equivalent like this:
#interface TheViewController : UIViewController
{
IBOutlet UITableView *table;
}
#property (nonatomic,retain) UITableView *table;
#interface TheViewController : UIViewController
{
}
#property (nonatomic,retain) IBOutlet UITableView *table;
Notice the added IBOutlet in the property definition.
Generally they're equivalent in Objective-C 2.0 environment, but the debugger, for example, won't see the generated ivar as this object's member in the variables view and you'll have to ask for the value by using gdb's command line po command using the accessor method (not the short-form dot notation though).

Adding Record using Core Data with Tab Bar Controller

I am trying to add a record to the database using core data. The appDelegate has the managed object model, context, and store coordinator setup in it. When the app is launched and I query the fetchResultsController method in one of my views the database is created matching the scheme with the correct table names and columns in it. However the problem comes when I try to add a record to the table.
The BurpListNavController.h file has the following contents (I am just learning):
#import <UIKit/UIKit.h>
#class BurpRecordController;
#interface BurpListNavController : UINavigationController <NSFetchedResultsControllerDelegate> {
BurpRecordController *burpRecordController;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
}
#property (nonatomic, retain) IBOutlet BurpRecordController *burpRecordController;
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
- (void)saveBurpLocal:(id)sender;
#end
I then have a view that records the burp, yes another one of the thousands of burp applications. haha. The following code is as follows:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
#class BurpLocal;
#class BurpListNavController;
#interface BurpRecordController : UIViewController <AVAudioRecorderDelegate, UIActionSheetDelegate> {
/*** Outlets to talk to the view ***/
IBOutlet UITextField *burpName;
IBOutlet UIButton *_recordButton;
/*** Standard Variables ***/
NSURL *recordedTmpFile;
//AVAudioRecorder *recorder;
NSError *error;
BurpLocal *burpLocal;
BurpListNavController *burpListNavController;
}
/*** Properties ***/
#property (nonatomic, retain) IBOutlet UITextField *burpName;
#property (nonatomic, retain) IBOutlet UIButton *recordButton;
#property (nonatomic, assign) IBOutlet BurpListNavController *burpListNavController;
#property(nonatomic, retain) BurpLocal *burpLocal;
/*** Method ***/
-(IBAction)saveRecording:(id)sender;
-(void)applicationWillTerminate:(NSNotification *)notification;
#end
When the end-user pushes the "save" button it calls the "saveRecording" method which I can step into and is great. Then I try to call the following line of code within the "saveRecording" method: [burpListNavController saveBurpLocal:sender]; thinking this will call the "saveBurpLocal" method in the nav controller and it just steps over it, does not stop at the break point in the nav controller method and then just goes to the end of the current "saveRecording" function. Does not write a record to the database or anything.
Please help! This is driving me crazy.
It's difficult to tell without more code; but it sounds like burpListNavController has not been set. When you step through the saveRecording: method, is the value of burpListNavController 0x0? If it is then you have forgotten to set that iVar somewhere.
If you have come from another language this might sound a little strange, as usually calling a method on a null pointer you cause you to crash. This isn't the case in Objective-C though, it is perfectly legal to send a message to nil; but don't expect anything to actually happen.

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