簡體   English   中英

源文件中的Objective-C成員變量vs屬性

[英]Objective-C member variable vs property in source file

我了解Object-C中成員變量和屬性之間的區別,但是有一件事讓我感到困惑。 請參閱以下代碼。

測試

@interface test : NSObject

@end 

測試

@interface test()
{
  NSString *memberStr;
}
@property (nonatomic, strong) NSString *properyStr;
@end

如圖所示,memberStr和propertyStr無法從外部看到。 我想知道它們之間有什么區別。 因為當我想使用局部變量時,我不怎么選擇解決方案。 謝謝!

properyStr將自動生成getter和setter。

您可以如下定義propertyStr自定義設置器。 當您使用self.propertyStr ,它將為您創建一個默認對象。 對於初始化諸如NSMutableArrayNSMutableDictionary等對象將很有用。

- (NSString *)properyStr
{
     if(_propertyStr == nil)
     {
          _propertyStr = @"";
     }
     return _propertyStr;
}

memberStr將沒有這些選項。

我了解Object-C中成員變量和屬性之間的區別

我不確定你會這么做。

成員變量是僅在實例方法范圍內可見的變量。

屬性是可以設置或獲取的類的某些屬性。 編譯器將編寫適當的getters和(可選)setters,並將自行組織存儲,除非您覆蓋其中任何內容。

成員變量和屬性都可以在@implementation@interface

成員變量永遠不能被不相關的類直接訪問,無論它在何處聲明。 如果在@interface則可以由子類訪問它。

始終可以讀取屬性,也可以選擇由任何其他類編寫屬性,而不管其在何處聲明。 外部類可以使用鍵值編碼機制,即使@property不可見。

因此,您可能會問的問題:

問)為什么要將成員變量放入@interface

答:不太可能。 它將其暴露給子類,但通常這樣做是設計缺陷。 但是,在過去,由於舊的Objective-C運行時的工作原理,必須將所有成員變量放入@interface 因此,較舊的代碼和慣用的程序員有時仍會遵循這種模式。

問)為什么我要聲明僅對@implementation可見的屬性?

答:不太可能。 但是,在過去,這是創建在@interface中不可見的成員變量的唯一方法,因此人們在短時間內處理大多數成員變量的方法也是如此。 同樣,您可以聲明一些內容,比如說retain ,然后使用getter / setter並假設正在進行正確的內存管理,因此在引入ARC之前,它就充當了某種語法糖。 與前面的答案一樣,因此有些人仍然通過習慣來這樣做,而有些代碼由於年紀較大而仍然這樣做。 這不是您如今經常要做的事情。

編輯:更好的摘要:屬性調整您的類接口 成員變量調整其實現 在面向對象的編程中,您應該將這兩件事視為完全不相交的

一個面向對象編程的主要目的之一是有一堆離散的演員是說:“我可以做X”與它們究竟是如何做到這一點是別人的事。

一個屬性說明一個類可以做什么。 成員變量的好處在於類如何實現。

從語義上講,它們是完全獨立的問題。

memberStr的第一個是實例變量或ivar。

如果您為此擁有一個屬性設置,則不再需要memberStr

@interface test()
@property (nonatomic, strong) NSString *properyStr;
@end

這樣做的原因是,將與setter和getter方法一起為您自動創建ivar。

與接口文件(.h)相比,在實現文件(.m)界面中聲明屬性的唯一區別是,該屬性僅對此類是私有的。 擁有此功能有很多優點,例如,您可能不想讓類外的任何人知道它,但是您希望該屬性仍在該類的范圍內。 它們以這種方式使用的一件事是,當您擁有一個聲明為public的只讀屬性,但仍希望該setter屬於此類的范圍時。 所以你可能會有類似

。H

@interface MyObject : NSObject

// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
@property (nonatomic, readonly) NSString *firstName;

@end

.m

@interface MyObject()

// But we still want to use the setter for this class only.
@property (nonatomic, strong) NSString *firstName;

@end

否則, 除了私有的只有類; 在實現文件(.m)中具有該屬性與在接口文件(.h)中具有該屬性完全相同,它們將起作用並執行相同的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM