Cocoa(Objective-C) 到 Lisp 的橋轉換基本規則 (教程翻譯)

Cocoa(Objective-C) 到 Lisp 的橋轉換基本規則 (教程翻譯)

=== 原文地址: 網絡: http://trac.clozure.com/ccl/wiki/CocoaBridgeTranslation
原文標題: Cocoa Bridge Translation 翻譯者: FreeBlues 2013-07-18網絡

===ide

目錄

0 概述

這裏有一堆從 OBJ-C 代碼到等效的 Clozure CL 的 Cocoa 橋代碼之間的轉換,示範不一樣的語言習慣如何編碼。這些東西有些是 Clozure CL FFI 的一部分,未指定具體的橋,但它們被包含在這裏給出一個整體概覽。函數

1 直接量 literals

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+

來表示它們.

2 類型 types

在其餘一些狀況下,您可能須要使用類型(不是類)名稱, 做爲您定義的方法的返回值。

Objective-C 的代碼爲:

NSInteger
BOOL

對應的 Lisp 代碼變爲:

#>NSInteger
#>BOOL

3 常量枚舉和變量 constants, enumerations and variables

Objective-C 的代碼爲:

NSTitledWindowMask
NSUTF8StringEncoding

對應的 Lisp 代碼變爲:

#$NSTitledWindowMask
#$NSUTF8StringEncoding

4 選擇器 selectors

Objective-C 的代碼爲:

@selector(someSelector:withParams:)

對應的 Lisp 代碼變爲:

(@selector "someSelector:withParams:")

譯者注:就是要去掉 Objective-C 代碼裏的括號--爲了不和 Lisp 的括號發生混淆

5 類定義 class definition

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))

6 方法定義 method definition

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 的風格來寫了.

7 實例化對象 instantiating objects

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)

8 方法調用 method call

Objective-C 的代碼爲:

[self doSomethingToObject:anObject];
[NSDate date];

對應的 Lisp 代碼變爲:

(#/doSomethingToObject: self an-object)
(#/date ns:ns-date)

譯者注: Objective-C 的方法調用語法爲:

[接收者 消息]

其中接收者是對象, 消息就是該對象要調用的方法, 因此寫成 Common Lisp 的形式就須要把先後順序調一下: 把方法函數放在前面, 調用方法函數的對象則做爲方法函數的參數傳遞給方法函數.

9 調用設置器/設置屬性 calling setters/setting properties

你可使用和調用任何其餘方法相同的方式來調用 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 通常​​沒有返回值。

相關文章
相關標籤/搜索