2011-06-24 43 views
1

我很難理解爲什麼我需要聲明實例變量。讓我解釋一下我的意思..Objective C的實例變量,爲什麼我應該聲明它們?

例如..

@interface LearningViewController : UIViewController { 
    UILabel *myText; // <--- Instance Variables 
} 

@property (nonatomic,retain) IBOutlet UILabel *myText; 

-(IBAction)method:(id)sender; 

@end 

這也可以作爲做

@interface LearningViewController : UIViewController { 
    //instance variables go here, but are not declared, I just leave this field blank 
} 

@property (nonatomic,retain) IBOutlet UILabel *myText; 

-(IBAction)method:(id)sender; 

@end 

,你可以看到。在後者的例子中,我只建造了setter/getter爲UILabel * myText

但在前者中我也聲明瞭實例變量。

雙方最終在年底工作

@implementation LearningViewController 

@synthesize myText; 


-(IBAction)method:(id)sender { 
    [myText setText:@"hey"]; 

    //or 

    NSString *myObject = [[NSString alloc]initWithString:@"hey"]; 

    [myText setText:myObject];  
} 

現在這兩件事產生相同的結果。所以我的問題是,爲什麼?這樣做的好處是什麼? 我爲什麼要建立和反對

NSString *myObject = [[NSString alloc]initWithString:@"hey"]; 

myText.text = myObject; 

時,我可以做

[myText setText:@"hey"]; 

在此先感謝。

回答

0

正如你的代碼演示的那樣,你在技術上不需要聲明實例變量,大多數情況下需要

一個關鍵的例外是,當您編譯舊的(< 4.0)iOS運行時,以及可能使用GCC的32位Mac OS X運行時,它不支持綜合實例變量。另外,如果你想爲後面增加的實例變量保留空間(如果你正在生成一個框架,並期望在稍後的時間點擴展一個類,可以是相關的),你需要顯式聲明實例變量。

編輯:長話短說:傳統,可移植性和可擴展性關切禁止明確的ivars。對於目標爲10.6,尤其是10.7的應用程序,很少或根本不需要聲明它們。

+0

謝謝賈利亞編輯我的帖子,我是相當新的在這裏提出問題(這是我的第一個問題),並感謝Williham爲了那個快速的回答。 – Andy

+1

iOS使用現代運行時,所以在iOS中依靠合成的ivars是很好的。它曾經是iOS模擬器使用舊運行時的情況,因此如果您使用模擬器,則不能使用合成的ivars,但現在不再是這種情況。 – Caleb

+0

@Caleb:確實;答案更新以反映這一事實。 –

0

在問題的第二部分,您只是簡單地使用點符號。你可以設置你的myText.text等於@「嘿」,就像你在第二個例子中那樣。

[myText setText:@"hey"]; 

是同義

myText.text = @"hey"; 

你並不需要聲明一個NSString可以提前把你的價值。

1

最初Objective-C沒有屬性,@ synthesize不存在。您必須聲明您的iVar(實例變量)並編寫您自己的setters和getters。

當語言和運行時修改爲包含屬性和@synthesize時,情況會更好。你不再需要編寫你的setter和getters。但是你仍然必須申報你的iVar。

後來,語言和運行時間演變得更多,今天,你甚至不需要聲明你的iVar。 (雖然我傾向於寫@synthesize example = _example;所以我可以控制生成的iVar命名的內容。)

這是一項新功能,只支持相對最新版本的運行時。與舊版本的OSX不同,iOS版本不支持4.x版本。

如果您正在爲今天和未來的軟件,來吧,讓他們出去,如果YOT需要傳統支持,讓他們進來。

0

你可以離開的ivars出來,但我不同意讓出高德。 OOP中的.h文件通常是一個顯示所有變量和方法的頭文件。它宣佈它們。假設將來你想看看這個類是幹什麼的,你只需引用.h文件即可。或者假設其他人需要查看該類,或者使用該類與他的代碼進行通信。它使得查看變量更容易,查看什麼是聲明的,什麼不是。也就是說,如果你想專業編程。

現在這取決於你想要做什麼。你將創建一個對象的原因是,所以你可以在稍後發佈它。所以你繼續使用它,當你完成後,你就完成了使用它。現在,當僅僅在一種方法中使用實例變量時,爲整個類創建實例變量不是一個好的設計決策。從某種意義上講,整個班級存儲變量的意義不大,實際上它只用於一種方法。在這種情況下,您應該只使用該方法創建該對象,並在完成後立即發佈該對象。

現在有時做

[myText [email protected]"hello"];

作品。這真的取決於你的代碼。我想,真正瞭解情況差異的唯一方法就是練習。有時您需要將標籤設置爲另一個對象,從而創建一個對象。否則,它會得到autoreleased等...

無論如何,基本上,使用實例變量僅適用於要在全球範圍內使用的變量。和UI元素當然(因爲它們被整個類和接口構建器使用)。

希望這會有所幫助。

+0

我看到你正在處理問題的最後一部分,但我看不到這個答案是書面的,減少了任何人的困惑。一個更簡單的答案可能是:「在你給出的例子中,沒有必要創建一箇中間對象;使用常量字符串是沒問題的。在其他情況下,可能需要在分配一個屬性之前分幾步配置一個對象。 「 – Caleb

+0

我的目標是幫助人們瞭解所有情況。另外在談論Obj-C時,很好的OOP和MVC設計。 – darksky

2

此外,有時您想在課堂中使用受保護的或私人的iVar,而不是使用其中的某個屬性。 (例如,當您不希望允許iVar訪問除此類(私有)或其後代(受保護)的實例以外的任何內容。標頭中聲明的屬性可用於任何可「看見」目標對象在信頭中自動聲明ivars作爲屬性(有或沒有大括號內的聲明)可能從信息隱藏的角度來看是不好的

你也可以在你的.m文件中添加一個實現部分:any你申明的屬性將會是私有的,這個好處顯然是在隱藏信息的地方,以及使用點符號的能力。

相關問題