访问Model类中的Controller数据成员

时间:2008-11-19 07:23:27

标签: objective-c cocoa

我正在使用Xcode开发GUI应用程序。我有一个模型类和一个控制器类。我的控制器类中有一个NSTextView数据成员。如何从模型类中访问此变量?

2 个答案:

答案 0 :(得分:11)

首先,模型类不应与视图类通信。 TextView是视图的一部分。

alt text http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/Art/cocoa_mvc.gif

控制器与视图类进行对话,视图类向控制器提供反馈。模型类由控制器更新并向其提供反馈。模型类从不与视图类通信,它们甚至不知道任何视图类的存在。所以我认为你有一个基本的设计问题。你可能在这个模型中实现了MVC:

alt text http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/Art/traditional_mvc.gif

然而,这不是在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)