#property declaration without #synthesizing - ios

I am following Big Nerd Ranch iOS Programming by Joe Conway and am kinda puzzled when I saw the following code.
WebViewController.h
#import <Foundation/Foundation.h>
#interface WebViewController : UIViewController
#property (nonatomic, readonly) UIWebView *webView;
#end
WebViewController.m
#import "WebViewController.h"
#implementation WebViewController
- (void)loadView
{
// Create an instance of UIWebView as large as the screen
// Tell web view to scale web content to fit within bounds of webview
}
- (UIWebView *)webView
{
return (UIWebView *)[self view];
}
#end
Shouldn't one synthesize the property declared in .h file? Xcode didn't give an warning either (which it usually does when I declare a property with synthesizing).
By the way, in the book, he also mentioned
In WebViewController.h, add a property (but not an instance variable)
Doesn't declaring a property automatically generate an instance variable for you? Let me know what I missed. Thanks.

This is a good question, and one to which I think the answer is a bit subtle and often not immediate to people starting out with Objective-C. First of all let's dispel a myth about properties. The myth is this:
Objective-C properties are related to instance variables.
This is not necessarily true. It is often true, but not true in every case. Here's what is true:
An Objective-C property declares a getter and a setter method
(Or in the case of a readonly property, just a getter). In particular when you declare a property called foo (for the sake of discussion, let's assume it's not readonly), the only thing you are really doing is telling the compiler that the class you're writing has a method called -foo and a method called -setFoo:. By adding an #synthesize foo; declaration into the .m file, you are telling the compiler to generate those methods itself. Here you are saying, "Compiler, create an instance variable (also called foo) and generate implementations for my -foo and setFoo: methods that access this instance variable. In particular, return the value of this variable in -foo and set the value of the variable in -setFoo:.
Note, it is not necessary to have the compiler synthesize the methods for you. Rather, you can write -foo and -setFoo: yourself. Furthermore, you are not in any way required to create an instance variable to support the implementation of these methods. You can write them however you wish.
To summarize: the #property only tells the compiler about the existence of the getter and setter methods. You can then either: #synthesize the methods in your .m or write the methods yourself.

This is because the "webView" getter method is implemented in the .m file and because of that, "#synthesize" isn't necessary.
If a "webView" method wasn't explictly created in code, then the compiler would complain about the property not being synthesized. Synthesizing a "read only" property, in this case, would only create a "getter" method which would do roughly the same thing you see in the code up there.
And yes, according to the Apple docs on declared properties, it says this about "#synthesize":
You use the #synthesize directive to tell the compiler that it should synthesize the setter and/or getter methods for a property if
you do not supply them within the #implementation block. The
#synthesize directive also synthesizes an appropriate instance
variable if it is not otherwise declared.

Related

Objective-C member variable vs property in source file

I understand the difference between member variable and property in Object-C, but there is one thing make me confused. See the following code.
test.h
#interface test : NSObject
#end
test.m
#interface test()
{
NSString *memberStr;
}
#property (nonatomic, strong) NSString *properyStr;
#end
As showed, the memberStr and propertyStr can't be see by outside. I want to know what is the difference between them. Because I don't how to chose the solution when i want to use local variable.
Thanks!
properyStr will have the getters and setters generated automatically.
you can define custom setter for propertyStr as below. When you use self.propertyStr, it will create a default object for you. It will be useful for initialising objects like NSMutableArray, NSMutableDictionary etc.
- (NSString *)properyStr
{
if(_propertyStr == nil)
{
_propertyStr = #"";
}
return _propertyStr;
}
memberStr will not have these options.
I understand the difference between member variable and property in Object-C
I'm not sure that you do.
A member variable is a variable that's visible only within the scope of instance methods.
A property is some attribute of the class that can be set or get. The compiler will write appropriate getters and, optionally, setters, and will organise storage for itself, unless you override any of those things.
Both member variables and properties can be declared either in the #implementation or in the #interface.
A member variable can never be accessed directly by unrelated classes, regardless of where it was declared. If it's in the #interface then it can be accessed by subclasses.
A property can always be read and, optionally, written by any other class, regardless of where it was declared. External classes can use the key-value coding mechanism even if the #property isn't visible to them.
Questions you may therefore be likely to ask:
Q) Why would I put a member variable into the #interface?
A) It's unlikely you would. It will expose it to subclasses but usually wanting to do so is a design flaw. However, in olden times you had to put all member variables into the #interface for reasons of how the old Objective-C runtime worked. So older code and stuck-in-their-ways programmers will still sometimes follow this pattern.
Q) Why would I declare a property visible only to the #implementation?
A) It's unlikely you would. However in olden times this was the only way to create member variables that weren't visible in the #interface so was the way people did most member variables for a brief period. Similarly, you could declare something, say retain, then use the getter/setter and assume correct memory management was going on, so it acted as some syntactic sugar in the days before ARC was introduced. As with the previous answer, there are therefore some people who still do so through habit and some code that still does so on account of being older. It's not something you'd often do nowadays.
EDIT: a better summary: properties adjust your class interface. Member variables adjust its implementation. In object-oriented programming you should be thinking of the two things as entirely disjoint.
One of the main purposes of object-oriented programming is to have a bunch of discrete actors that say "I can do X" with exactly how they do it being nobody else's business.
A property says what a class can do. A member variable is for the benefit of how the class does it.
Semantically they're completely separate issues.
First of memberStr is an instance variable or ivar.
There is no need to have memberStr any more if you have a property setup for this all you need is.
#interface test()
#property (nonatomic, strong) NSString *properyStr;
#end
The reason for this is that the ivar will be automatically created for you along side the setter and getter methods.
The only difference between declaring the property in the implementation files (.m) interface over the interface file (.h) is that it will be private to this class only. There are many advantages for having this such as maybe you don't want anything outside of the class to know about it but you want the property to be in scope for this class still. One thing that they are used for in this manner is when you have a readonly property declared public but you still want the setter to be in scope for this class. So you may have something like
.h
#interface MyObject : NSObject
// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
#property (nonatomic, readonly) NSString *firstName;
#end
.m
#interface MyObject()
// But we still want to use the setter for this class only.
#property (nonatomic, strong) NSString *firstName;
#end
Otherwise except for being private to that class only; having the property in the implementation file (.m) will be the exact same as having it in the interface file (.h) they will act and do the same thing.

Synthesizing CGFloat property in iOS

I declared a property as below. From my readings on the web, it is not clear if I should also synthesize as below. I have seen supporting blog posts for two different approaches.
#property (assign, nonatomic) CGFloat someFloat;
Then in the implementation:
#synthesize someFloat = _someFloat;
I have also seen in some cases:
#synthesize someFloat;
From readings, I understand that "someFloat" is a property name, and "_someFloat" is created through the synthesis. So I am under the impression that the first way is correct. However, I have used the second approach without problems. And I have seen the second approach in other code and blogs.
Can someone tell me what is the correct way and why?
In general, you no longer need to manually write #synthesize anymore. In your example, if you write
#property (assign, nonatomic) CGFloat someFloat;
The compiler will automatically synthesize it for you, which would be equivalent to you writing
#synthesize someFloat = _someFloat;
Hence, you would be able to access the property through self.someFloat or access the ivar within the implementation file by using _someFloat.
If, however, you manually synthesize it like
#synthesize someFloat;
The compiler automatically creates a backing ivar titled someFloat... thereby, you would still be able to access the variable through the getter self.someFloat (that is, equivalent to [self someFloat] call).
Or, you could access the ivar by simply using someFloat somewhere within the implementation...
In general, it's not recommended to synthesize like this because it's quite easy to accidentally use the ivar when you meant to access the variable using the getter.
EXCEPTION TO THE RULE
The compiler still gets confused with synthesizing variables sometimes, however, in certain instances. For example, if you have a class that is a subclass of NSManagedObject, then you still need to write the #synthesize manually (assuming, of course, you actually want to synthesize the property... you likely don't though...).
The reason for this is two-fold: (1) the compiler doesn't seem to understand these properties very well yet (or at least it doesn't in the cases I've worked with), and (2) many times, you actually DON'T want to #synthesize properties on an NSManagedObject subclass... rather, you want them to be #dynamic instead (so the getter/setter will be generated at runtime, per requirements of NSManagedObject subclass magic).
Just skip the #synthesize statement, the compiler will generate the same thing as if you had:
#synthesize someFloat = _someFloat;

Should I declare variables in interface or using property in objective-c arc?

approach 1:
#interface MyController : UIViewController {
UILabel *myText;
}
#property (nonatomic, strong) UILabel *myText;
approach 2:
#interface MyController : UIViewController
#property (nonatomic, strong) UILabel *myText;
approach 3:
#interface MyController : UIViewController {
UILabel *myText;
}
I have read some articles talking about this kind of stuff but I still do not really realize which approach I have to adopt.
I also found that someone said approach 1 is a old way so I would like to know the best practice for ios sdk 6 using ARC.
I know that declaring variables using property is a easy way for generating getter and setter and someone suggested using it. However, I would like to ask in case a variable is not for calling by another class, is it necessary for the variable using property? and set it as private variable inside the interface? Or is it better for a variable only declaring inside the interface? I would like to learn the best practice so please forgive me if this is a silly question.
Moreover, some developers write #synthesize in this way
#synthesize myText=_myText;
but some write this:
#synthesize myText;
I would also want to know the difference and which one is preferable?
Thank you very much!
The most modern way1:
whenever possible, declare properties
don't declare iVars separately 2
don't #synthesize 3
locate as few properties as possible in you .h file 4
locate as many properties as possible in a class extension in your .m file 5
1 As of Xcode 4.5.2. Most of this applies back to 4.4, some of it won't compile on 4.2 (the last version available under Snow Leopard). This is preprocessor stuff, so it is all compatible back at least to iOS5 (I haven't tested on iOS4 but that should also be OK).
2 There is no point in declaring an iVar as well as a property. I am sure there are a few obscure cases where you would want to declare iVars instead of properties but I can't think of any.
3 Xcode will create an iVar with the same name as the property, preceded by an _underscore. If you (rarely) need some other kind of behaviour, you can manually #synthesize property = someOtherName. #vikingosegundo links us to this article on dynamic ivars, which is a use case for #synthesize. #RobNapier comments that you do need to #synthesize iVar = _iVar (bizarrely) if you are creating your own getters (readonly) and setters (read/write) for a property, as in this case the preprocessor will not generate the iVar for you.
4 The general rule with your interface: keep it as empty as possible. You don't actually need to declare your methods now at all, if they are for private use. If you can get the code to work without an interface declaration, that's the way to go.
5 This is an #interface block in your .m file, placed above your #implementation:
#TestClass.m
#interface TestClass()
//private property declarations here
#end
#implementation TestClass
...
You may also want to use #synthesize if you like a nice table of contents of your #synthesized properties that you can refer to and comment for clarity and organization.
Also, an #synthesize allows you to set a breakpoint on the property and trap when its value is changed.
When the compiler does everything for you, you end up being distanced from what is really happening and ignorant to it. However, not having to type out everything yourself all the time is also nice.

Declaring variables in .h file

Just wondering if its good programing practice to have a lot of variables declared in the .h file.
I'm writing my first app through which im learning xcode and obj-c. This ios app has just one xib, one .m and one .h file. I find my self a lot of times where i have a certain variable that i need to use in different methods/places in the .m file and i just end up declaring it in the .h file which seems like im making the variable global which i dont think is a good idea to have a lot of those.
Is this safe/ok to have a lot of variables declared in .h file or should i approach it in some other way?
Thanks
Is this safe/ok to have a lot of variables declared in .h file or
should i approach it in some other way?
It's absolutely OK to include a lot of variables in the .h! It just increases compile time a little and increases the size of your binary by an arbitrary amount. If it worries you, just split your implementation across a couple of categories.
I find my self a lot of times where i have a certain variable that i need to use in different methods/places in the .m file and i just
end up declaring it in the .h file which seems like im making the
variable global which i dont think is a good idea to have a lot of
those.
Variables that are accessed outside of one method should always be declared as iVars, and as properties if they require strong reference, or need to be accessed by outside classes. Global variables are way different, and you needn't worry about it.
Your .h file is the public interface of your class. It should only contain properties and methods that other classes need to know about.
You can declare ivars and internal methods and properties in a class continuation in the .m file (this is so common that one is now automatically included in the template for UIViewController subclasses).
You can also declare ivars within braces directly after the #implementation.
In iOS5, with ARC, declared ivars are strong references by default, so you don't have to use properties or accessor methods, but that choice depends on the rest of your class. For example, you may use lazy instantiation or perform other tasks or KVO when getting or setting a variable, in which case you'd always want to access it via a property or method, and if you're doing that for some ivars, and not others, it starts to look a bit messy.
It is alright for you to have many variables declared in the interface in the .h file when needed (as touched on by the other answers). But it would be wise for you to consider moving instance variables that do not need to be public into a category in the .m file. For example:
In the .h:
#import <Foundation/Foundation.h>
#interface SomeClass : NSObject {
NSDictionary *publicDict;
NSArray *privateArray;
}
#property (nonatomic, strong) NSDictionary *publicDict;
-(void)publicMethod:(id)anObj;
#end
And in the .m file:
#import "SomeClass.h"
#interface SomeClass () //Category that denotes private methods
#property (nonatomic, strong) NSArray *privateArray;
-(void)privateMethod;
#end
#implementation
#synthesize publicDict;
#synthesize privateArray;
-(id)init {
//...
}
-(void)publicMethod:(id)anObj {
//..
}
-(void)privateMethod {
//..
}
#end
This causes the compiler to issue a warning whenever any of the private methods contained in that category are accessed by outside classes. Additionally, this is the widely accepted way of adhering to an aspect of encapsulation in Objective-C.

xcode basic explanation needed

I am actually a newby at xcode. I can make out a few things be myself but have questions about what some things do and why they are put there. I have tried to read many e-books, watched tutorials, but they never go into the basics, alway just say "Add this, Click here etc"
Could someone give me some answers to a few questions please.
Ok, I know an ios app is mostly made out of Views, views are controlled by controllers. Each controller has a header (.h) file and a module?class? file (.m). The .h file contains the declarations of variables and functions used in the .m file.
The whole app is controlled by a master "controller" called the "delegate".
Definitions in .h file may be for example an action IBAction or IBLabel or something.
What raises questions for me is for example these lines:
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#interface FlipsideViewController : UIViewController
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
and why are sometimes in another view controller the delegate class loaded
#class MainViewController;
what does the following do, meaning what is the #interface declaration?
#interface flipAppDelegate : NSObject <UIApplicationDelegate>
what is
nonatomic, retain
sorry for asking really stupid questions, but every tutorial just skips these things.
I can follow a youtube video or a manual, but it doesn't teach me a lot...
Let me try to answer your questions, one at a time.
what is the #interface declaration?
The interface declares a class. By declaring a class, I mean it specifies the instance variables and private/public methods that it contains. Again, the header file only contains the declaration of the methods, and the implementation/body of the methods lies in the module class. So, here-
#interface FlipsideViewController : UIViewController
The class FlipsideViewController derives from/subclasses/extends UIViewController. i.e Is a type of UIViewController but adds its own features.
Similarly
#interface flipAppDelegate : NSObject <UIApplicationDelegate>
Subclasses NSObject and implements the UIApplicationDelegate protocol. A protocol is essentially a set of methods that a class promises to implement (although there can be optional methods).
why are sometimes in another view controller the delegate class loaded
The delegate pattern allows a class to delegate its work to another class that implements the delegate protocol. So, here, FlipsideViewController keeps an instance of the delegate object, so that its flipsideViewControllerDidFinish: can be called.
what is nonatomic, retain
It means that when you set a value to your instance variable, the value's refcount will be incremented and set to your variable. Also, it will not happen as an atomic operation. You need atomic only in a multi-threaded environment.
#synthesize is simply a shortcut to generate getters and setters for your variables.
You really need to read the Objective-C Programming Language from Apple. It's pretty brief, and runs down the basics of the architecture, concepts, and syntax.
To address, briefly, some specifics:
The #class directive is used to declare the name of a class without importing it's header file. It is often used in a .h file declaring a protocol, because a protocol has no implementation, it doesn't need to import the interfaces of other classes (their .h files).
A protocol is a way of declaring what methods and properties a class should have in order to "implement" the protocol.
#interface is used in an interface file (.h) to declare a class, meaning to describe the methods and properties it will have, the protocols it will implement, and the superclasses from which it will inherit. In your example, the class will be called flipAppDelegate, which inherits all of the methods and properties of the NSObject class, and which implements the UIApplicationDelegate protocol.
In your class (.m) file, you will define (with all your code) all of the methods and properties that you declared in your interface file. You include the methods and properties you declared yourself, and from the protocols you implement.
#synthesize is used in a class implementation file (.m) to "synthesize" --- that is, automatically create the code for --- all the properties you declared in your interface (.h) file. Since properties normally just need basic accessors (a "getter" that just returns the current value, and a "setter" that just sets the current value), using #synthesize is a shortcut to let the compiler create the variable to store the value, the getter method, and the setter method for you automatically.
Xcode = An IDE (Integrated Development Environment)
Objective-C = A Language
Cocoa Touch, Media FrameWork, Core FrameWork = Frameworks used in developing for iOS
I'd highly recommend starting by learning Objective-C. At least with a primer first:
https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/_index.html
There's a wealth of tutorials and videos available from Apple for developers you might want to start on the developer portal.

Resources