Pisanie metod natywnych

J2ObjC obsługuje umieszczanie języka Objective-C w natywnych metodach Javy, podobnie jak JSNI GWT obsługuje Umieszczanie JavaScriptu. Główną różnicą między wektorem dystrybucyjnym J2ObjC a GWT jest to, że J2ObjC używa /*-[ i ]-*/ do nakreślenia kodu Objective-C. Instytucja ta nosi nazwę OCNI (Objective-C) interfejsu natywnego), aby odróżnić się od JSNI GWT.

Oto przykład z wersji java.lang.System dostępnej w bibliotece emulacji JRE:

  public static native long currentTimeMillis() /*-[
    // Use NSDate
    return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
  ]-*/;

J2ObjC kopiuje komentarz (bez separatorów), aby utworzyć treść metody:

  + (long long int)currentTimeMillis {
    // Use NSDate
    return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
  }

Importy natywne

J2ObjC skanuje tłumaczony kod Java, aby dodać dyrektywy #import do zależności oraz jak importowanie platformy podstawowej. Jednak wszelkie importy wymagane tylko przez kod natywny muszą dodane oddzielnie. Aby dodać importy, dodaj sekcję OCNI nad pierwszą klasą w pliku źródłowym Javy i określić tam importy, np.:

  package my.project;

  /*-[
  #import "java/lang/NullPointerException.h"
  ]-*/

  public class Test {
    native void test() /*-[
      @throw [[JavaLangNullPointerException alloc] init];
    ]-*/;
  }

W powyższym przykładzie import jest niezbędny, ponieważ jedynym miejscem, do którego się odwołuje się ten typ, jest kodu natywnego.

Bloki natywne

W treści klasy J2ObjC skanuje w poszukiwaniu bloków OCNI. Bloki te są dodawane bez zmian do przetłumaczony plik w tej samej pozycji względem przetłumaczonych elementów zajęć. Oto przykład:

  /*-[
    static void log(NSString *msg) {
      NSLog(@"%@", msg);
    }
  ]-*/;

Tę funkcję C można wywołać z dowolnych metod natywnych zadeklarowanych po tym bloku OCNI.

Specjalny wariant tego bloku OCNI wstawia kod do wygenerowanego nagłówka. z pliku .m: /*-HEADER[...]

Wywoływanie metod Java z kodu natywnego

public native void bar(JSNIExample x, String s) /*-[
  // Call instance method instanceFoo() on this
  [self instanceFooWithNSString:s];

  // Call instance method instanceFoo() on x
  [x instanceFooWithNSString:s];

  // Call static method staticFoo()
  JSNIExample_staticFooWithNSString_(s);
]-*/;

Uzyskiwanie dostępu do pól z kodu natywnego

Aby odczytać pole instancji, użyj myInstanceField_ lub self->myInstanceField_ Sufiks na końcu pozwala uniknąć konfliktu z metodami o tej samej nazwie.

Pamiętaj, że pola z zarezerwowanymi nazwami będą miały 2 podkreślenia. Przykład: pole o nazwie „id” jest zgodny z prawem w języku Java, ale nie w Objective-C. Po przetłumaczeniu pole będzie nazywać się „id__”. Sprawdź wygenerowane pliki, jeśli nie ma takiego pola kompilatora.

Aby zapisać dane w polu instancji obiektu, użyj JSNIExample_set_myInstanceField(string)

Odczytaj pole statyczne: JSNIExample_get_myStaticField()

Wpisz pole statyczne: JSNIExample_set_myStaticField(value)

J2ObjC i GWT

Wybrano różne separatory, tak że w następnej wersji J2ObjC komentarze GWT JSNI zostaną ignorowanych (wcześniej te same separatory były używane jako GWT). Oznacza to, że jedno źródło w Javie może mają metody natywne z implementacją Objective-C, GWT i Android (przez JNI):

  static native void log(String text) /*-{ // left-brace for JavaScript
    console.log(text);
  }-*/ /*-[                                // left-bracket for Objective-C
     NSLog(@"%@", text);
  ]-*/;

J2ObjC i Android

J2ObjC i natywne metody Androida „po prostu działają”, bo metody natywne Androida wdrożony w osobnym pliku JNI C lub C++. Wszystkie komentarze OCNI w klasach Java są usuwane, gdy skompilowane przez javac dla Androida lub dowolnej innej platformy Java.