some confusions about " property" in Objective-C - iphone

#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).

Related

objective c multiple inheritance conflict with many

I just started to build in objective c from iphone.
I have interface:
#interface test : UIView
that implements all methods from UIView, now i want it interface inherit from CDVPlugin also.
How can i do it?
i read that objective c doesn't offer multiple inheritance.
you can't inherent from CDVPlugin and UIView.
I would suggest doing something like this
#interface test : NSObject {
UIView *view;
CDVPlugin *plugin;
}
#property(nonatomic, retain) UIView *view;
#property(nonatomic, retain) CDVPlugin *plugin;
#end
and you can add methods to that class to handle anything that you're trying to do. Then just use test.view to access the view and test.plugin to access the plugin.

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

private and public property in objective-C

So what is actually the difference between these two versions:
#interface Foo : NSObject
// A guy walks into a bar.
#property(nonatomic, copy) NSString *bar;
#end
// Implementation file
#interface Foo ()
#property(nonatomic, retain) NSArray *baz;
#end
and
#interface Foo : NSObject
// A guy walks into a bar.
#public
#property(nonatomic, copy) NSString *bar;
#private
#property(nonatomic, retain) NSArray *baz;
#end
As far as my understanding goes, putting the #property in the .m basically means that it is private. Correct me if I am wrong? Also which is the best implementation then? Is it just a coding style/practice?
The compiler can warn you about things that it knows about.
When I import your header the compiler can see that Foo has a method called bar and setBar:. This means I can use them both
[instanceOfFoo setBar:#"some string"];
NSLog(#"%#", [instanceOfFoo bar]);
whereas because I only imported the header - the compiler can only see the header it is not aware that there are also methods baz and setBaz: available, so doing the following will cause the compiler to barf
[instanceOfFoo setBaz:#"some string"];
NSLog(#"%#", [instanceOfFoo baz]);
I can however still access these properties if I know they exist by using KVC like this without the compiler barfing
[instanceOfFoo setValue:#"some string" forKey:#"baz"];
NSLog(#"%#", [instanceOfFoo valueForKey:#"baz"]);
You are correct in your understanding. Putting the #property in an #interface in the .m is making it "private". What that means is you'll get compiler warnings if you try to access that property from another class that includes the .h that doesn't include the #property declaration. This doesn't mean that you can't access the property, just that the compiler will yell at you.
As for best, neither one is best. You should implement the one that makes sense for you object, which could include items in both the .h and .m (read only proper in .h with full property in .m). Basically if the #property shouldn't ever be accessed outside of your class put it in the .m.

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.

With & Without UITextFieldDelegate?

I am curious about conforming a class to UITextFieldDelegate, in the past I have always added it to enable access to methods defined within the protocol. However this last time I forgot to add it, only realising later that it was missing. My question is why does it work with or without, I thought it was needed to correctly access the protocol methods?
#interface MyController : UIViewController <UITextFieldDelegate> {
UITextField *text_001;
}
#property(nonatomic, retain) IBOutlet UITextField *text_001;
#end
OR:
#interface MyController : UIViewController {
UITextField *text_001;
}
#property(nonatomic, retain) IBOutlet UITextField *text_001;
#end
WITH:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(#"Return: ... ");
[textField resignFirstResponder];
return YES;
}
Cheers Gary
Delegate declarations are really just there as compiler hints; obviously, you still have to implement the underlying methods. However, the main purpose is to let the compiler double check you when assigning them. If you try to manually (in code, as opposed to IB) assign a delegate which wasn't declared as such, you'll frequently get a compiler warning.
Since Objective-C uses duck-typing for most stuff (if it walks like a duck and quacks like a duck; if it responds to -textFieldShouldReturn:, etc), you're pretty safe.