感谢您花时间阅读本文,希望能帮助我!
我是第一次使用Objective-C和Cocoa在Xcode 4中编写我的第一个程序。我一直在关注这些教程,但此时我想使用自定义视图显示自定义图形,其中图形根据模型对象中的值进行更改。
我的控制器类GameController基于NSObject,在初始化期间创建我的模型对象,并成功接收按钮动作消息,适当地更新模型对象,并使用其出口更新窗口上的文本字符串。我通过在我的xib文件中创建一个NSObject对象(它被称为MainMenu.xib的默认(?)名称,但它包含我的应用程序中的所有UI),使用实用程序窗格将其类设置为GameController,以及然后将其动作和出口连接到适当的UI元素。
我已将自定义视图拖到窗口中,并使用实用程序窗格将其类设置为我的自定义视图类BoardView,它基于NSView。在BoardView中,我覆盖了drawRect:用蓝色填充我的视图背景,然后绘制我的模型类(GameStatus)定义的每个图形。
问题是,我不知道如何从我的BoardView类访问GameStatus中的数据,或者让GameController更新BoardView的成员变量。我没有在Interface Builder中的任何地方实例化BoardView,只需在我的窗口上删除自定义视图。我的xib文件中没有BoardView对象(Interface Builder左侧的列或列表)。
我尝试在我的GameController类中创建一个BoardView对象的插座(我的xib中有一个对象,如上所述),并在我的窗口中将该插座连接到BoardView自定义视图,Interface Builder似乎很好。但是,当我运行程序时,我的GameController类中的BoardView插座指针的值是0x0。好像插座没有连接到BoardView对象。我不知道我是否需要在Interface Builder中做一些其他的东西来制作一个实际的对象(我尝试在左边的列表中创建一个,但后来无法想出一种方法将它连接到显示的实际自定义视图在窗口上。)
为了增加混乱,当我运行我的应用程序时,窗口的BoardView区域将显示蓝色背景,实际上我在drawRect:函数中定义的任何其他图形。但是,没有任何方式与我的模型对象交谈,我无法根据模型的状态更改图形。我不确定硬编码图形是否正确显示的事实意味着某处有一个对象,或者它是否以某种方式基于该类的通用模板进行绘制。后者对我来说没有意义,但如果前者是真的,我无法弄清楚如何从我的代码的其他部分与该对象交谈。
我觉得我只是缺少对Xcode / Interface Builder如何创建对象或其他东西的基本理解。我真的很感激有人告诉我我在MVC对象/类之间的连接中到底发生了什么。
提前感谢您提供给我的任何帮助!
编辑2011/09/06: 要下载我的项目副本以查看它,请转到此处: http://talix.homeip.net/2011/rival/ 这是我的家庭服务器,我是一个业余爱好者,所以如果它不起作用请发表评论。谢谢!此外,如果有更好的方式来回复评论我的原始帖子以外的评论,请告诉我们;我也是这个网站的新手。 ; - )
-Joe
答案 0 :(得分:0)
听起来你只是在实例化一个GameController
和一个BoardView
,而这正在笔尖中发生。
这就是问题的核心所在:
我尝试在我的GameController类中创建一个BoardView对象的插座(我的xib中有一个对象,如上所述),并在我的窗口中将该插座连接到BoardView自定义视图,Interface Builder似乎很好。但是,当我运行程序时,我的GameController类中的BoardView插座指针的值是0x0。好像插座没有连接到BoardView对象。
在您的代码中,您需要引用BoardView但是获得nil?那是在GameController的init方法中,还是在GameController的其他一些方法中?
如果它在init中,这就是我所期望的。加载nib的代码必须在连接出口之前初始化对象。
(如果它在init之外,我建议先断开连接并重新连接插座。)
在MVC中,控制器通常代理模型和视图之间的通信,所以我建议你这样处理:
drawRect
中,让BoardView从游戏控制器获取游戏状态。我还建议您将GameController作为应用程序的委托:
RivalAppDelegate.[hm]
。GameController.h
@interface GameController : NSObject
之后,添加<NSApplicationDelegate>
GameController.m
中,实施applicationDidFinishLoading
并在那里设置您的应用。 (如果您愿意,甚至可以在那里拨打setGameStatus
。)