2014-03-28 38 views
0

在Objective-C中發送「消息」是一個主體運行時函數,當我們編譯我們的源代碼時(雖然objc_msgSend),它會得到調用。屬性設置器是否在Objective-C中發送消息?

如果我正確理解「消息發送」是針對實例變量。由於沒有弱指針或強指針的屬性沒有在堆中初始化,因此調用setter屬性不會「發送消息」,它只會調用@property自動創建的「函數」,即-(void)setNumber:(int)number,這發生在堆棧中對?

+3

發送消息通常會調用接收對象上的方法。財產(如果不告訴其他的話)爲ivars創建setter和getter。getter和setter只是方法。你能結束其餘的嗎? – vikingosegundo

回答

3

由於沒有弱或強指針性在堆不被初始化,調用setter的屬性不會「發送消息」

它會發送消息。在你的例子中,setNumber:方法是擁有int的對象的一部分 - 這是發送消息的對象,而不是int,它根本不能成爲消息的目標。

@interface Demo : NSObject 
@property (nonatomic, readwrite) number; 
@end 

Demo *demo = [[Demo alloc] init]; // Creates the object 
// The following two lines are identical - they both send setNumber to demo 
demo.number = 123; 
[demo setNumber:123]; 

這也是不正確的說,原語未初始化的堆:是他們的「主人」對象的一部分,他們總是從動態內存分配。事實上,他們沒有以與id屬性相同的方式指向其他堆內存並不會改變屬性本身的分配位置。

2

聲明:「消息發送是爲變量實例」不正確。消息發送在對象實例之間完成。實質上,「發送消息」在給定參數的特定對象上執行方法。您可以將方法視爲對象的特定「功能」。由於屬性只是getter和setter方法,因此訪問屬性將「發送消息」,因爲它調用設置/獲取屬性值的對象的方法。

此外,「由於沒有弱或強指針的屬性未在堆中初始化」是不正確的。屬性只是一個吸氣劑(- (NSString *) name;)和setter(- (void) setName:(NSString *)name;)的組合。屬性本身可能會或可能不會被實例變量支持,但「屬性」的定義與「堆」或「堆棧」直接無關。

實例變量(所有變量)可以位於堆或堆棧上,具體取決於該變量是什麼。如果它是一個基元(int,double等),它作爲堆棧中的一個值存在。如果變量是一個對象(類型爲ID或*),則該對象將存在於堆棧中,並且該堆棧上具有指向該對象的指針。這個例外是c塊,它是(據我所知)在棧上初始化的唯一對象,但這是一個不同的對話。知道變量是否在堆上(是對象)的最簡單方法是它是否具有類型ID,或者您是否看到星號*作爲類型的一部分。

您可以查看屬性作爲「訪問者」。它們被設計爲獲取或設置與某個對象相關的值,但該對象本身確定「獲取」和「設置」是如何完成的。你不能假定對象是如何做到這一點的。它可能會保留值的後備實例變量,但它也可以很容易地將值保留爲其他值的組合。完全取決於如何存儲和檢索值的對象。