我确信这是一个简单的问题,但到目前为止它一直难以捉摸,而且我很难过......
如何声明Ivar以便可以从项目中的所有类访问它?
[不知道它是否重要,但有问题的ivar是我的Model类的一个实例,其数据需要可供各种视图控制器访问。]
我可以在 Objective-C 2.0编程语言中"The Scope of Instance Variables”告诉我 ......这将是使用“@public”指令。
所以我在声明了ivar的@interface块中尝试了这个:
@interface ...
...
@public
ModelClass *theModel;
@end
...但是当我尝试在另一个类中引用“theModel”时,编译器不会自动完成,当我以任何方式输入它时,编译器会显示: “错误:'theModel'未声明(首次使用此功能)”。
我认为这是一个范围问题,而且我没有适当地提供ivar,但是如何?不知何故,我需要访问它,或以某种方式使其指针可用。
任何想法都会非常感激。非常感谢!
答案 0 :(得分:5)
也许您忘了将实例变量放在所有实例变量声明所在的类的大括号内?
@interface Foo : NSObject {
// other instance variable declarations
@public
ModelClass *theModel;
}
// method and property declarations
@end
另外,您能否向我们展示您如何尝试从其他地方访问实例变量的代码?正确的语法应该是:
myFooInstance->theModel
其中myFooInstance
是“Foo *
”
答案 1 :(得分:3)
您无法从任何其他类访问iVars。
你必须声明一个getter / setter方法来改变或查看另一个类的变量 - 你真正想要的是属性,这样可以更容易地定义和访问这些getter / setter方法。
在上面的示例中,您将在定义头文件中的局部变量的块之后定义属性:
@property (nonatomic, retain) ModelClass *theModel;
在实现文件中,您将在@implementation行之后使用@synthesize语句创建getter / setter:
@synthesize theModel;
然后,如果您创建了类的实例,则可以像下面这样访问类实例变量:
myInstance.theModel = [[[ModelClass alloc] init] autorelease];
@public& @private用于定义子类的可见性(该类的扩展也可以获取超类定义的所有类本地变量),而不是任何随机类。
答案 2 :(得分:3)
我通过表示我的数据模型的单例,使Tab Bar管理的所有视图都可以使用属性。这是有效的,并允许所有视图访问数据(以及任何其他应用程序元素。创建单例是直截了当的(SO上有大量示例)。您只需请求实例并获取所需的属性值。
这是创建Singleton的框架。关键点是静态实例以及初始化为[[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;
}
答案 3 :(得分:1)
标准的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]
答案 4 :(得分:0)
想一个C全局变量。
添加:
extern ModelClass* theModel;
在标题中的@end
之后,只要您包含标题,变量就会显示。
在ModelClass.cpp文件中添加:
ModelClass* theModel;
在课前实施。
在您分配并初始化变量之前,变量的值仍然为nil,并且您将负责确保在正确的时间取消分配。
答案 5 :(得分:0)
感谢大家就此主题进行非常有益的讨论!显然,有几种方法可以在这里处理,所以这是一种非常有用的技术分类。
只是让大家都知道,在进一步研究这个问题时,我遇到了一些其他非常有用的页面,如下所示。它们包括我之前从未听说过的NSNotificationCenter;以及“依赖注入”设计模式的想法。
这个想法是在类之间保持“低耦合”(1),使代码更加模块化。更适合单元测试。
虽然'通知'模式听起来像个好主意,但在这种情况下它可能有点矫枉过正,考虑到我在应用程序运行期间只需要一个数据模型实例,并且它不会改变整个
最后,即使Apple的 Obj-C 指南(2)中详细记载了“@public”编译器指令,我后来在另一个文档中发现了一个引人入胜的法令,声明它不应该使用!引自Apple自己的 Cocoa Fundamentals (3):
“为你的实例变量赋予适当的范围。永远不要将变量作为@public范围,因为这违反了封装原则。......”
(奇怪的是他们没有在他们的'Objective-C 2.0'指南中提到这个指令实际解释过。)
无论如何,这里有一些其他链接我发现也充满了一些很棒的见解。供参考:
S.O。:“什么是最好的方法 沟通之间 viewcontrollers?“(4)<<
CocoaWithLove:“五种方法 倾听,观察和通知 可可“(5)
CocoaWithLove:“单身人士, AppDelegates和顶级数据“(6)
希望这些帮助。无论如何,再次感谢大家!
最佳, ROND
P.S。哎呀!它不会让我发布多个内联超链接,所以我在这里列出它们。显然,它们的前缀都是“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