我正在使用Xcode开发GUI应用程序。我有一个模型类和一个控制器类。我的控制器类中有一个NSTextView数据成员。如何从模型类中访问此变量?
答案 0 :(得分:11)
首先,模型类不应与视图类通信。 TextView是视图的一部分。
控制器与视图类进行对话,视图类向控制器提供反馈。模型类由控制器更新并向其提供反馈。模型类从不与视图类通信,它们甚至不知道任何视图类的存在。所以我认为你有一个基本的设计问题。你可能在这个模型中实现了MVC:
然而,这不是在Mac OS X中完成的方式,这不是Apple的方式,这不是整个Cocoa对象结构的设计方式!所以你的问题的答案是:你没有,因为你不应该。
除了您有设计缺陷这一事实之外,您可以像访问Objective-C中的所有数据成员一样访问它。如果是公开的,您可以直接访问它:
MyController * c = [[MyController alloc] init];
// c has a member name textView, let's access it
[c->textView ...];
你应该已经知道,这实际上是非常糟糕的编程风格。您不应直接访问其他对象的数据成员。你实际上甚至不应该公开它们。如果您将它们声明为私有,则上面的代码将失败(编译器会强制您不执行此操作)。另一种方法是实现一个getter并通过getter访问它:
// This goes into the controller
- (NSTextView) textView
{
return textView;
}
// This is called in the modell
[[c textView] ...];
然而,这也是糟糕的设计。该模型可能会对此对象执行任何操作,您的控制器将无法看到它!你为什么不建模只是告诉控制器它想要发生什么?
// In the controller
- (void) notifyContentHasChanged:(NSString *)name
{
// update the text view here ...
}
// In the modell
[c notifyContentHasChanged:...];
瞧,你有MVC就像Apple希望的那样。该模型仅通知控制器发生了什么,控制器相应地更新了视图。
答案 1 :(得分:1)
Re:递归#import
问题,你要找的是@class
指令。在大多数情况下,所有类接口都需要了解其他类是否为其名称,因为所有实际特定于实现的内容都在您的*.m
文件中。因此@class
指令为接口定义提供了一种告诉编译器的方法“嘿,当你遇到这个词时,它是一个类名,所以不要惊慌失措。”在接口声明中使用@class
时,不需要导入该类的头文件。
The Objective-C 2.0 Programming Language: Class Interface (Referring to Other Classes)