Reputation: 2405
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.
Upvotes: 0
Views: 2504
Reputation: 5820
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.
Upvotes: 5
Reputation: 89559
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.
Upvotes: 3