Help: Instance Variables & Properties [iPhone] - iphone

In something like this:
#interface Control_FunViewController : UIViewController {
UITextField *nameField;
UITextField *numberField;
}
#property (nonatomic, retain) IBOutlet UITextField *nameField;
#property (nonatomic, retain) IBOutlet UITextField *numberField;
I understand that "UITextField *nameField;" is an instance variable and "#property ..." is a property. But what do these individual things do?
I guess what I'm really asking is how the property is used for example in the implementation file (.m)

The instance variables are the actual variables, whereas the properties are the equivalent of
- (UITextField *)nameField;
- (void)setNameField:(UITextField *)newTextField;
and completely optional. They are also used by the compiler to understand exactly what you want when you #synthesize a variable. Basically the properties and corresponding #synthesize (or custom implementation) allow OTHER classes access to variables, and are completely optional. It is in fact generally recommended, as per standard object oriented encapsulation principals, not to use properties unless you specifically intend for them to be used by external classes. However, you still need Interface Builder to recognize the UITextFields (presumably) which is why we typically put the IBOutlet decorator before the ivar declaration, not the property.

Related

issue with custom delegate and datasource

I have a custom delegate and datasource. But I have several problems with it when I try to initialize it. In my .h file if have it like this.
#property (nonatomic, assign) id<UITableViewDelegate> delegate;
#property (nonatomic, assign) id<KalDataSource> dataSource;
This has as an result that in the synthesize in the .m file I get the following error.
Existing ivar 'dataSource' for property 'dataSource' with assign attribute must be __unsafe_unretained.
After some google search magic I found that I should assing my variables like this.
#property (nonatomic, strong) id<UITableViewDelegate> delegate;
#property (nonatomic, strong) id<KalDataSource> dataSource;
But then I get this error.
linker command failed with exit code 1 (use -v to see invocation)
Can anybody help me with this?
Kind regards!
The error you're experiencing has nothing to do with your memory qualifiers (they were right the first time around). The problem lies in the fact that you have declared a backing iVar somewhere without qualifiers. When iVars are declared, they are implicitly strong, so if you go to your shadowing iVars, and prepend __weak or __unsafe_unretained, the warning should disappear. Of course a better solution would be to just remove your backing iVars altogether, because Xcode will synthesize them for you.
Delegates are usually weak references.
The object using the delegate doesn't own it.
It's just a reference to an object which could, or could not be responding.
Weak says, that if the real owner of the object releases it, it should be deallocated.
The weak reference is then automatically set to nil and you don't get any zombies.
Second, the problem is, that you already have property called dataSource.
EDIT
My previous statement about the duplicate property turns out to be wrong.
You should override the setters & getters, both the declaration in the .h and the implementation in the .m file.

objective-c interface - declaring variable vs just property?

In Obj-c when declaring a variable within #interface
#interface: NSObject{
MyObject* myObject}
#property (unsafe, nonatomic) MyObject* myObject;
Vs. Only declare it as a property
#interface: NSObject{}
#property (unsafe, nonatomic) MyObject* myObject;
#end
Not declare any var here?
Regards
Christian
#property defines an interface, not an implementation. In your case, you're defining a readwrite property. This means that you're promising to implement -myObject and -setMyObject:. This has nothing to do with ivars.
Now, the most common way to implement those methods is by having them be backed by an ivar. As a convenience, ObjC lets you automatically generate the required methods with an ivar store using #synthesize myObject=myObject_; This says "create the required methods for the property myObject using an automatically created ivar called myObject_." The ivar myObject_ is a real ivar, and you can access it normally (though you generally shouldn't; you should use accessors).
Instead of using #synthesize, you could just implement -myObject and -setMyObject:. You could even use #dynamic myObject; to tell the compiler "don't worry about the implementations for this property; it'll be handled correctly at runtime."
There are a few differences between #property and just declaring methods, but in principle, this line:
#property (nonatomic, readwrite, strong) MyObject* myObject;
is conceptually the same as this:
- (MyObject *)myObject;
- (void)setMyObject:(MyObject *)anObject;
Declaring the ivar yourself has no real impact here. You still need to implement the methods somehow. If your named ivar is the same as the ivar #synthesize is using, then #synthesize just won't create a new ivar.
As a matter of practice, I discourage people from declaring ivars anymore. I recommend just using public and private properties with #synthesize to create any needed ivars. If you must have a manual ivar for some reason, then I recommend declaring them in the #implementation block rather than the #interface.
Skipping declaring the ivar is perfectly fine--but you will not be able to see the ivar's value in the Xcode IDE. One day Apple may fix this.
You will be able to "po" the ivar to inspect it in GDB or lldb.

Questions about instance variables and declaring their properties

If I declare instance variables and objects in my header between brackets with "IBOutlet" in front of them, do I have to set the objects properties?
Also does this mean they are private? What does it mean for them to BE private???
If you do #property and #synthesize you do not have to declare variables. The .h file is an api for a class so declaring anything inside it, has an intension to be public rather than private.
To declare IBOutlet private, you need to create a category,
#interface YourViewController ()
#property (nonatomic, retain) IBOutlet UILabel *label;
#end
Above code will be inside .m file.
Hope this will help
No,It is not necessary to set properties for IBOutlets, Just declaring them would be enough
for eg:
IBOutlet UIbutton *btn;
If you want the variables to be private then you will have to declare it in this form
#interface myclass:NSObject
{
#private
int var1;
}
Instance variables declared as private in a class can be accessed only by an instance of the class.
You just have to declare variables of an object as IBOutlets (assuming you are hooking them up using Interface Builder). They don't have to be properties unless you have a reason to make them a property (i.e. you want the variable to be accessible by other objects). A private property can't be accessed by an external object.

Instance Variable Syntax Question

When declaring an instance variable, does it make a difference if I declare it under #interface and as a #property? Example:
#interface MyViewController : UIViewController {
NSString *myString;
}
#property (nonatomic, retain) NSString *myString;
Would it matter if I took out the one under #interface? I have been doing that and would like to know if it does anything.
With a modern compiler (recent versions of LLVM), there is no need to declare the instance variables in conjunction with an #property (as tc says; it is the #synthesize that actually tells the compiler to reserve a slot, otherwise, you are on your own for storage) and doing so doesn't change anything.
One suggestion; when you #synthesize, do something like #synthesize myString = myString_; to cause the iVar to have a different name and, thus, make it impossible to accidentally directly access when you meant to go through the property.

Question on UIApplicationDelegate generated by Xcode

I'm trying on objective-C and Xcode 4, and get some bit I don't understand.
The following code are generated by the Xcode for a view-based iphone application:
In the .h file:
#interface viewexampleAppDelegate : NSObject <UIApplicationDelegate> {
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet viewexampleViewController *viewController;
#end
In the .m file:
#synthesize window=_window;
#synthesize viewController=_viewController;
So the question is:
where is the _window and _viewController comes from? I didn't see any declaration or initialization of them.
Objective-C allows declaring properties without having to explicitly declare the corresponding backing instance variables. Instead, instance variables are synthesized as needed. In this case, by default the name of the backing instance variable is the same as the declared property name. So, assuming the class hasn’t declared an instance variable called something,
#synthesize something;
would implicitly create an instance variable also called something.
It is also possible to have the instance variable be named differently from the declared property, e.g.
#synthesize something = _something;
The compiler then creates a backing instance variable called _something in case one doesn’t already exist.
With regard to initialisation, both properties are IBOutlets. This usually means that their corresponding instances are loaded from a nib file, and the nib file has outlets connecting those properties to actual objects.