=== 原文地址: 网络: http://trac.clozure.com/ccl/wiki/CocoaBridgeTranslation
原文标题: Cocoa Bridge Translation 翻译者: FreeBlues 2013-07-18网络
===ide
这里有一堆从 OBJ-C 代码到等效的 Clozure CL 的 Cocoa 桥代码之间的转换,示范不一样的语言习惯如何编码。这些东西有些是 Clozure CL FFI 的一部分,未指定具体的桥,但它们被包含在这里给出一个整体概览。函数
T 和 NIL 被映射到对应的布尔值 YES 和 NO. 全部数字也是可移植的. NSStrings 须要被明确地建立:编码
Objective-C 的代码为:翻译
@"some string"
对应的 Lisp 代码变为:指针
#@"some string"
若是你须要在 Lisp 字符串和 NSStrings 之间作转换, 下面的函数就是你想要的.code
(let ((a-lisp-string "foo")) (ccl::%make-nsstring a-lisp-string))
而且当你接收到 NSStrings 时,你一样须要转换:对象
(ccl::lisp-string-from-nsstring (#/title some-object))
Clozure CL 习惯于自动转换字符串, 不过这很容易引发内存管理问题. 因此必定要确保你所须要的任何 NSStrings 的保持/释放.教程
nil NULL
这两个都是空指针. 在 Lisp 中要使用:接口
ccl:+null-ptr+
来表示它们.
在其余一些状况下,您可能须要使用类型(不是类)名称, 做为您定义的方法的返回值。
Objective-C 的代码为:
NSInteger BOOL
对应的 Lisp 代码变为:
#>NSInteger #>BOOL
Objective-C 的代码为:
NSTitledWindowMask NSUTF8StringEncoding
对应的 Lisp 代码变为:
#$NSTitledWindowMask #$NSUTF8StringEncoding
Objective-C 的代码为:
@selector(someSelector:withParams:)
对应的 Lisp 代码变为:
(@selector "someSelector:withParams:")
译者注:就是要去掉 Objective-C 代码里的括号--为了不和 Lisp 的括号发生混淆
Objective-C 的代码为:
@interface SomeClass : SuperClass { IBOutlet NSString *aString; }
译者注: 这段的代码其实是 Object-C 中对一个类的接口的定义, 保存在 .h 文件中,也就是头文件, 使用语法形式为:
@interface 类名:父类名 { 实例变量声明; } - 实例方法声明; + 类方法声明; @end
对应的 Lisp 代码变为:
(defclass some-class (super-class) ((a-string :foreign-type :id)) (:metaclass ns:+ns-object))
Objective-C 的代码为:
@implementation SomeClass // just included so we show the class name - (id) initWithFrame:(NSRect)frame andStuff:(id)stuff { if ((self = [super initWithFrame:frame])) { // body } return self; } - (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // body }
译者注: 这段的代码其实是 Object-C 中对一个类的实现的定义, 具体内容为类的方法的实现代码, 保存在 .m 文件中,也就是存放代码的文件中, 相似于 C 的 .c 文件, 使用的语法形式为:
@implementation 类名 - 实例方法实现 + 类方法实现 @end
对应的 Lisp 代码变为:
(objc:defmethod (#/initWithFrame:andStuff: :id) ((self some-class) (frame #>NSRect) (stuff :id)) (let ((new-self (#/initWithFrame: self frame))) (when new-self ;; body ) new-self)) (objc:defmethod (#/viewDidAppear: :void) ((self some-class) (animated #>BOOL)) (call-next-method)) ;; body )
一般有 CALL-NEXT-METHOD (仅如预期在 OBJ-C 方法中工做),可是,这并不包括你在 OBJ-C 中须要的全部使用场景。如同在 init 方法中常见的,有时你须要使用跟当前方法不一样的名字来调用一个 super-method。这就是 CALL-NEXT-METHOD 失败的地方。在上面的例子中, 本身来处理这个问题的最简单的方法是, 把调用 super 当作 调用 self 。
译者注:由于 Common Lisp 的面向对象系统 CLOS 的实现机制跟 Objective-C 有很大的不一样, Lisp 的面向对象是基于广义函数的, 而 Objective-C 的面向对象是基于消息的, 因此这里的 Lisp 代码尽可能按照 Objective-C 的风格来写了.
Objective-C 的代码为:
[[NSWindow alloc] initWithContentRect:NSRectMake(0, 0, 300, 300) styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:YES];
对应的 Lisp 代码变为:
(make-instance 'ns:ns-window :with-content-rect (ns:make-ns-rect 0 0 300 300) :style-mask #$NSTitledWindowMask :backing #$NSBackingStoreBuffered :defer t)
Objective-C 的代码为:
[self doSomethingToObject:anObject]; [NSDate date];
对应的 Lisp 代码变为:
(#/doSomethingToObject: self an-object) (#/date ns:ns-date)
译者注: Objective-C 的方法调用语法为:
[接收者 消息]
其中接收者是对象, 消息就是该对象要调用的方法, 因此写成 Common Lisp 的形式就须要把先后顺序调一下: 把方法函数放在前面, 调用方法函数的对象则做为方法函数的参数传递给方法函数.
你可使用和调用任何其余方法相同的方式来调用 setter ,但要想使它们的工做更像是属性或槽,您也能够对它们使用 SETF。
Objective-C 的代码为:
[self setName:aName]; self.name = aName; // provided there is a @property defined
对应的 Lisp 代码变为:
(#/setName: self aName)
或者是
(setf (#/name self) a-name)
而 SETF 形式不管是否有一个定义好的属性都将工做,但必须存在一个 getter (例如 (#/name self))。这是由于 SETF 的用户指望把保存值返回,但 Cocoa 的 setters 通常没有返回值。