没有@synthesizing的@property声明

时间:2012-06-12 03:50:48

标签: ios properties synthesize

我正在关注Joe Conway的Big Nerd Ranch iOS编程,当我看到以下代码时,我有点不解。

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

不应该合成.h文件中声明的属性吗? Xcode也没有给出警告(当我声明一个带有合成的属性时它通常会这样做)。

顺便说一下,在书中,他也提到了

  

在WebViewController.h中,添加属性(但不是实例变量)

不声明属性会自动为您生成实例变量吗?让我知道我错过了什么。感谢。

2 个答案:

答案 0 :(得分:5)

这是一个很好的问题,我认为答案有点微妙,往往不会立即开始使用Objective-C。首先,让我们消除关于财产的神话。神话是这样的:

Objective-C属性与实例变量相关

这不一定是真的。 经常是真的,但在每种情况下都不是真的。这是真的:

Objective-C属性声明了一个getter和一个setter方法

(或者在readonly属性的情况下,只是一个吸气剂)。尤其是当你宣布一个名为属性foo(为便于讨论,我们假设它不是只读),你真的做的唯一的事情是,告诉你写的类有一个方法{编译{1}}以及名为-foo的方法。通过在.m文件中添加-setFoo:声明,您告诉编译器自己生成这些方法。在这里,您要说,“编译器,创建一个实例变量(也称为@synthesize foo;),并为访问此实例变量的foo-foo方法生成实现。特别是,返回值setFoo:中此变量的值,并在-foo中设置变量的值。

注意,没有必要让编译器为您合成方法。相反,您可以自己编写-setFoo:-foo。此外,您无需以任何方式创建实例变量来支持这些方法的实现。你可以随意写下它们。

总结一下:-setFoo:只告诉编译器getter和setter方法的存在。然后,您可以:@property .m中的方法或自己编写方法。

答案 1 :(得分:3)

这是因为“webView”getter方法是在.m文件中实现的,因此,“@synthesize”不是必需的。

如果在代码中没有明确地创建“webView”方法,那么编译器会抱怨该属性未被合成。在这种情况下,合成一个“只读”属性只会创建一个“getter”方法,它与你在代码中看到的大致相同。

是的,根据Apple docs on declared properties,它说的是“@synthesize”:

  

使用@synthesize指令告诉编译器它应该合成属性的setter和/或getter方法   你没有在@implementation块中提供它们。的的   @synthesize指令还合成了一个合适的实例   变量,如果没有另外声明。