[英]Public scope in Objective-C?
我確信這是一個簡單的,但到目前為止它是難以捉摸的,我很難過......
如何聲明Ivar以便可以從項目中的所有類訪問它?
[不知道它是否重要,但有問題的ivar是我的Model類的一個實例,其數據需要可供各種視圖控制器訪問。
... this would be by using the “@public” directive. 從中 “實例變量的范圍”可以看出最好的...這將是使用“@public”指令。
所以我在聲明了ivar的@interface塊中嘗試了這個:
@interface ...
...
@public
ModelClass *theModel;
@end
...但是當我嘗試在另一個類中引用“theModel”時,編譯器不會自動完成,當我無論如何鍵入它時,編譯器顯示:“錯誤:'theModel'未聲明(首先使用於這個功能)“。
我認為這是一個Scope的問題,我沒有適當地提供ivar,但是如何? 不知何故,我需要訪問它,或以某種方式使其指針可用。
任何想法都會非常感激。 非常感謝!
也許您忘了將實例變量放在所有實例變量聲明所在的類的大括號內?
@interface Foo : NSObject {
// other instance variable declarations
@public
ModelClass *theModel;
}
// method and property declarations
@end
另外,您能否向我們展示您如何嘗試從其他地方訪問實例變量的代碼? 正確的語法應該是:
myFooInstance->theModel
其中myFooInstance
是“ Foo *
”類型的值
您無法從任何其他類訪問iVars。
您必須聲明一個getter / setter方法來更改或查看另一個類中的變量 - 您真正需要的是屬性,這樣可以更容易地定義和訪問這些getter / setter方法。
在上面的示例中,您將在定義頭文件中的局部變量的塊之后定義屬性:
@property (nonatomic, retain) ModelClass *theModel;
在實現文件中,您將在@implementation行之后使用@synthesize語句創建getter / setter:
@synthesize theModel;
然后,如果您創建了類的實例,則可以像這樣訪問類實例變量:
myInstance.theModel = [[[ModelClass alloc] init] autorelease];
@public和@private的原因在於定義子類的可見性(該類的擴展也可以獲取超類定義的所有類本地變量),而不是任何隨機類。
我通過表示我的數據模型的單例使Tab鍵欄管理的所有視圖都可以使用屬性。 這是有效的,並允許所有視圖訪問數據(以及任何其他應用程序元素。創建單例是直截了當的(SO上有大量示例)。您只需請求實例並獲取所需的屬性值。
這是創建Singleton的框架。 關鍵點是靜態實例以及初始化為[[self alloc] init];
的事實[[self alloc] init];
。 這將確保正確清理對象。 該類底部的所有方法都是SDK Docs的標准方法,以確保忽略發布調用(因為該對象是全局共享的)。
Singleton Boilerplate(ApplicationSettings.m):
static ApplicationSettings *sharedApplicationSettings = nil;
+ (ApplicationSettings*) getSharedApplicationSettings
{
@synchronized(self) {
if (sharedApplicationSettings == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedApplicationSettings;
}
+ (id)allocWithZone:(NSZone *)zone
{
@synchronized(self) {
if (sharedApplicationSettings == nil) {
sharedApplicationSettings = [super allocWithZone:zone];
return sharedApplicationSettings; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
標准的Objective-C方法是使用返回ivar的類方法
在你的.h文件中:
+ (id)defaultModel;
並在您的.m文件中:
static ModelClass * defaultModelInstance;
@implementation ModelClass
+ (id)defaultModel {
if (!defaultModelInstance) {
defaultModelInstance = [[ModelClass alloc] init];
}
return defaultModelInstance;
}
@end
雖然這需要調整,如果你需要一個特定的ivar而不是只是“一個總是相同的ivar”
很多Cocoa類都使用這種類型的設計,即[NSWorkspace sharedWorkspace]
想一個C全局變量。
添加:
extern ModelClass* theModel;
在標題中的@end
之后,將變量顯示在包含標題的任何位置。
在ModelClass.cpp文件中添加:
ModelClass* theModel;
在類實現之前。
在您分配和初始化變量之前,變量的值仍然為nil,並且您將負責確保在正確的時間取消分配。
謝謝大家就此話題進行非常有益的討論! 很明顯,這里有幾種方法可以處理,所以這是一種非常有用的技術。
只是讓大家都知道,在進一步研究這個問題時,我遇到了一些其他非常有用的頁面,如下所示。 它們包括我之前從未聽說過的NSNotificationCenter; 以及“依賴注入”設計模式的想法。
我們的想法是在類之間保持“低耦合”(1),使代碼更加模塊化,更好地進行單元測試。
雖然“通知”模式聽起來是個好主意,但在這種情況下,考慮到我在整個應用程序運行過程中只需要一個數據模型實例,它可能有點過分,而且它並沒有隨時改變。
最后,盡管Apple的Obj-C指南(2)中詳細記載了“@public”編譯器指令,但我后來在另一個文檔中發現了一個引人入勝的法令,聲明它不應該被使用 ! 引自Apple自己的Cocoa Fundamentals (3):
“為你的實例變量賦予適當的范圍。永遠不要將變量作為@public范圍,因為這違反了封裝原則。......”
(奇怪的是,他們沒有在他們的“Objective-C 2.0”指南中提到這一點,其中實際解釋了該指令。)
無論如何,這里有一些其他鏈接我發現也充滿了一些很棒的見解。 供參考:
那么: “在viewcontrollers之間進行通信的最佳方式是什么?” (4)<<
CocoaWithLove: “在Cocoa中傾聽,觀察和通知的五種方法” (5)
CocoaWithLove: “單身人士,AppDelegates和頂級數據” (6)
希望這些幫助。 無論如何,再次感謝大家!
最好的,好的
PS呀! 它不會讓我發布多個內聯超鏈接,所以我在這里列出它們。 顯然,它們的前綴都是“http://”......:O
(1):en.wikipedia.org/wiki/Coupling_(computer_science)
(2):developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Articles/ocDefiningClasses.html#//apple%5Fref/doc/uid/TP30001163-CH12-TPXREF127
(3):developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/AddingBehaviorCocoa.html#//apple_ref/doc/uid/TP40002974-CH5-SW12
(4):stackoverflow.com/questions/569940/whats-the-best-way-to-communicate-between-viewcontrollers
(5):cocoawithlove.com/2008/06/five-approaches-to-listening-observing.html
(6):cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.