我们知道在Cocoa程序中, 如果你想处理一个窗口的事件或者应用程序的事件, 你可以使用Delegate的方法来实现响应的事件处理函数,但是如果你要处理一个button控件或者一个窗口里面很多的类似Button的这种有一种缺省行为的控件的时候, 是不是要为他们每个控件都来实现这个Delegate呢?答案是否定的,因为针对这些具有指定的缺省行为的控件,NSControl已经帮我们进行了一部分的处理(这个control要求继承自NSActionCell, 比如你添加一个Button到窗口中,那么对Button的Click事件,NSControl是有自己的处理的,这就是Target-Action模式,当Button的click事件被触发是,NSControl就会去检查这个Control中是否有对应的Target,这个Target针对这个事件处理的Action是什么,如果Target和Action都存在,那么这个Click事件就会被NSControl直接处理,类似的处理代码如下(假设的实现)
-(void) mouseClicked()
{
if (target != nil && action != nil && [target respondsToSelector:action])
{
[target performSelector:action withObject:self];
}
}
下面我们通过具体的代码来展示一下这个技术。
#import <Cocoa/Cocoa.h>
@interface MyController : NSObject
{
}
- (void) onButtonClicked:(id)sender;
@end
@implementation MyController
- (void) onButtonClicked:(id)sender
{
[NSApp terminate:NSApp];
}
@end
int main(int argc, char *argv[])
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
//Create main window
NSRect rc = NSMakeRect(0, 0, 800, 600);
NSUInteger uiStyle = NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask;
NSBackingStoreType backingStoreStyle = NSBackingStoreBuffered;
NSWindow* win = [[NSWindow alloc] initWithContentRect:rc styleMask:uiStyle backing:backingStoreStyle defer:NO];
[win setTitle:@"HelloWin Test"];
//Create a button and set it as content view
NSButton* button = [[NSButton alloc] initWithFrame:NSMakeRect(200, 200, 60, 40)];
[button setTitle:@"Quit Application"];
[win setContentView:button];
//Set target and action
MyController* controller = [[MyController alloc] init];
[button setTarget:controller];
[button setAction:@selector(onButtonClicked:)];
[win center]; //Center main Window
[win makeKeyAndOrderFront:win];
[win makeMainWindow];
[NSApp run];
[button release];
[win release];
[pool drain];
return 0;
}
上面这段代码首先创建了一个窗口,然后在窗口内创建了一个Button,这个Button作为窗口的ContentView呈现,因为NSButton是从NSView继承来的,所以也是NSView的一个实例。在创建了Button对象之后,我们就为这个Button对象设置了用来处理缺省事件的Target对象,然后又通过setAction来设置处理这个事件的方法, 这里要注意的是这个Action方法一定是可以被Target响应的,也就是说符合respondsToSelector:的调用。
这个Target对象的实现被放在一个叫做MyController的类里面,它实现了一个方法叫做onButtonClicked:,这个方法被作为一个Action方法,所以它有一个参数(id)sender,这是因为Action方法被调用的时候,调用者会将触发这个Action的对象通过这个参数传递给Action方法。这个例子的实现很简单,直接调用NSApp对象的Terminate:方法来退出应用程序。
这个例子结束的地方和以前有所不同, 我分别调用了Button和Window的release方法,这是因为Window和Button对象都是通过引用形式分配的,所以当不再需要使用的时候需要将他们所占用的资源释放掉。Obj-C 2.0中提供了Garbage Colletion的功能,你分配的对象会在不被使用的时候自动释放,不过如果能了解Cocoa对象的分配和释放模式,对我们理解整个Cocoa框架的实现还是大有益处的。
上面这个例子还有一个地方需要注意的是Button的大小,你可以看到在代码中我为button分配的Rect的大小是60x40,但是运行的时候你会发现这个Button充满了整个Windows的Content区域,这是因为这个Button作为Window的ContentView,而Window的ContentView的Size Policy是随父窗口改变高度和宽度的。如果我们将
[win setContentView:button];
这句代码注释掉,换成下面的这句
[[win contentView] addSubview:button];
那么这个Button就在窗口中被正确定位了, 但是当你改变窗口大小的时候,这个Button的位置和大小都没有改变,这个是由它的Sizing Policy决定的。
原帖:http://www.cocoachina.com/bbs/read.php?tid=27&keyword=target|action
分享到:
相关推荐
设计模式之 Template(模板方法) 实际上向你介绍了为什么要使用 Java 抽象类,该模式原理简单,使用很普遍. 设计模式之 Strategy(策略) 不同算法各自封装,用户端可随意挑选需要的算法. 设计模式之 Chain of ...
Target模式下的性能分析是关键,因为它直接影响到整个存储网络的实时性和稳定性。作者提出了一套可移植、稳定的Target端优化方案,旨在解决负载均衡问题,并提升读写性能。 此外,文章还关注了Initiator端对Target...
根据提供的文件信息,我们可以从标题“编译原理英文版”以及描述“英文版编译原理,有用到的同学可以看一下,希望会有所帮助”中提取出与编译原理相关的知识点。接下来,我们将对这些知识点进行详细说明。 ### 编译...
《编译原理》是计算机科学领域的一本经典教材,由陈火旺教授编著的第三版,涵盖了编译器设计的各个方面。这本书深入探讨了如何将高级编程语言转化为机器可执行的指令,即编译器的工作原理。在这里,我们将重点讨论书...
东北大学的编译原理课程设计是学生们深入理解这一过程的重要实践环节。2013年的课程设计包含了实验代码和实验报告,这不仅展示了学生们的编程技能,还反映了他们对编译器构造的理解。** 在这个项目中,学生可能经历...
清华大学的《编译原理》课件可能涵盖了这些知识点,并提供了深入的理论讲解和实例分析,帮助学生逐步掌握编译器的设计与实现。通过学习,学生不仅能理解编译器的内部工作,还能为未来在软件开发、编程语言设计和工具...
清华大学的《编译原理》第二版是一本深受学生和专业人士欢迎的教材,它深入浅出地介绍了编译器的设计与实现过程。这份课件正是基于该教材的精华内容进行整理,旨在帮助学习者更好地理解和掌握编译器的构建技巧。 ...
这些课件可能涵盖了上述的所有编译原理知识点,并可能包含实例解析、习题解答以及实践项目,帮助学生深入理解编译器的设计与实现。通过学习这些课件,不仅可以掌握编译器的基本原理,还能提升解决问题和分析代码的...
《清华版编译原理课后答案》是一份涵盖了编译原理多章节内容的详细解答集,对于学习者来说,这是一份极其宝贵的参考资料。编译原理是计算机科学领域中的核心课程,它研究如何将高级编程语言转换为机器可执行的低级...
通过阅读本分析文档,读者将能够全面理解Kbuild的工作原理及其背后的机制。 #### Kbuild简介 Kbuild主要由两部分构成:`Kconfig` 和 `Kbuild` 文件。其中,`Kconfig` 负责处理配置信息,而 `Kbuild` 则负责具体的...
适配器模式是一种软件设计模式,它允许两个不兼容的接口之间进行通信。在软件工程中,当系统中存在一个已经存在的组件,但其接口与我们当前系统的需求不匹配时,适配器模式就能派上用场。适配器模式通过创建一个...
Ant的设计目的是为了简化Java项目的构建过程,使得开发者可以在任何支持Java的平台上使用相同的构建脚本来进行项目构建。 ##### 1.2 Ant的优势 - **跨平台性**:由于Ant本身是用Java编写的,因此可以在任何支持Java...
例如,可能会有题目要求设计一个简单的词法分析器,或者分析一段代码并指出其对应的抽象语法树结构。此外,对编译器设计的基本原理、编译器构造工具(如LEX和YACC)的了解也是考试的重要部分。 通过研读这份“bbs....
编译原理是计算机科学中的一个重要领域,主要研究如何将高级编程...通过这个实验,学生不仅能学习到编译原理的理论知识,还能动手实践,提高问题解决能力和软件工程技能,为后续更复杂的编译器设计和优化打下坚实基础。
此核心IP包含了PCI总线的所有必要组件,可以大大简化设计过程。 - **Initiator**:负责发起PCI总线上的事务,如读写操作等。 - **Target**:接收来自Initiator的请求,并作出响应。 #### 五、PCI总线设计的协议层 ...
5. **代码优化(Code Optimization)**:优化阶段旨在提高生成代码的效率,通过分析中间代码,消除不必要的计算,减少指令数量,改善内存访问模式等。常见的优化技术有常量折叠、循环展开、寄存器分配等。 6. **...
在学习编译原理时,读者会接触到如正则表达式、上下文无关文法、LR分析、LL分析、LLVM等概念和技术。通过学习,不仅可以掌握编译器的设计与实现,还能深入理解编程语言的底层机制,对提升软件开发的水平大有裨益。 ...
通过学习陈意云教授的编译原理课程,不仅可以掌握编译器设计的基本原理,还能培养严谨的逻辑思维能力和问题解决技巧,这对于软件开发、系统级编程、甚至是计算机硬件设计等领域都有着深远的影响。对于计算机专业的...
词法分析器(词法分析器生成器如LEX/Flex)负责识别这些模式。 3. **语法分析(Syntax Analysis)** - **语法分析3.ppt**:语法分析阶段,编译器检查词法单元序列是否符合语言的语法规则,通常采用上下文无关文法...