2012-06-12 240 views
0

我正在關注Big Nerd Ranch由Joe Conway編寫的iOS編程,當我看到下面的代碼時,感到困惑不解。@property聲明沒有@synthesizing

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,添加屬性(但不是一個實例變量)

不聲明屬性自動生成你有一個實例變量?讓我知道我錯過了什麼。謝謝。

回答

3

這是因爲「webView」getter方法在.m文件中實現,因此「@synthesize」不是必需的。

如果「webView」方法未在代碼中明確創建,則編譯器會抱怨未合成的屬性。合成一個「只讀」屬性,在這種情況下,只會創建一個「getter」方法,這個方法與你在代碼中看到的大致相同。

是的,根據Apple docs on declared properties,它說這個關於「@synthesize」:

你使用@synthesize指令來告訴它應該合成爲一個屬性的setter和/或者getter方法編譯如果 您不在@implementation塊中提供它們。 @synthesize指令還會合成適當的實例 變量(如果未另行聲明)。

+0

我明白了!非常感謝你的幫助!不能相信我錯過了吸氣。 – revolver

+0

的XCode的最新版本自動合成屬性您 –

5

這是一個很好的問題,我認爲答案有點微妙,而且通常不會立即開始使用Objective-C。首先,讓我們消除一個關於物業的神話。神話是這樣的:

Objective-C屬性與實例變量有關。

這不一定是正確的。它是經常是是真的,但在每種情況下都是不正確的。這裏是什麼是真正的:

Objective-C的屬性聲明一個getter和setter方法

(或在readonly屬性的情況下,只是一個getter)。特別是當你聲明一個名爲foo的屬性時(爲了討論的緣故,我們假設它不是隻讀的),你唯一要做的就是告訴編譯器你正在編寫的類有一個叫-foo的方法, -setFoo:。通過在.m文件中添加@synthesize foo;聲明,您告訴編譯器自己生成這些方法。在這裏,你會說:「編譯器,創建一個實例變量(也稱爲foo)並且爲我的-foosetFoo:訪問這個實例變量的方法實現。特別是,返回該變量的值-foo,並設置變量的值在-setFoo:

注意,這是沒有必要的,可以讓編譯合成方法適合你。相反,你可以寫-foo-setFoo:自己。而且,你是不是在創建一個實例變量來支持所需的任何方式。實施這些方法你可以寫他們自己的喜好

總結:在@property只告訴編譯器有關getter和setter方法的存在。然後,您可以:在.m中使用方法@synthesize或者自己編寫方法。

+0

感謝您的解釋! – revolver

+0

如何在沒有合成的情況下設置/獲取屬性仍然工作? – GeneCode