簡體   English   中英

Objective-C中的公共范圍?

[英]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.

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