Bölümlendirilmiş Üstbilgiler

J2ObjC tarafından oluşturulan başlık dosyaları segmentlere ayrılır ve tek seferde bir segment dahil edilebilir. Her çevrilmiş Java türü için bir segment oluşturulur. Bu nedenle, her iç sınıfın kendi segmenti olur. Önişleyici makroları, derleyiciye üstbilgiyi dahil ederken yalnızca belirli bir segmenti okumasını söylemek için kullanılır. Segmentlere ayrılmış üstbilgiler, bu dokümanda ayrıntılı olarak açıklanan J2ObjC tarafından oluşturulan üstbilgilerde döngü dahil etme sorununu çözer.

Bilmeniz gerekenler

  • J2ObjC tarafından oluşturulan üstbilgileri dahil etmek için #import yerine #include kullanın.
    • Derleyici daha önce gördüğü başlığı atlayacağı için #import'ü segmentlere ayrılmış başlıklarla kullanmak sorunludur. Ancak başlık segmentlere ayrıldığından derleyici tarafından ilk kez tam olarak ayrıştırılmamış olabilir.
  • Segmentlere ayrılmış üstbilgiler, --no-segmented-headers işaretiyle devre dışı bırakılabilir.

Sirküler İçeriği

J2ObjC tarafından oluşturulan başlık dosyaları, gerekli tür bilgilerini çözmek için dahil etme ve ileri beyan kullanmalıdır. Olası olduğunca ileriye dönük bildirimler kullanılır. Ancak derleyici tam tür tanımını gerektirdiğinden, türlerin genişletilmesi veya uygulanması için dahil etme işlemleri gereklidir.

J2ObjC tarafından oluşturulan başlık dosyalarında dahil döngüsü oluşturmak mümkündür. Böyle bir döngü elde etmek için A dosyasında B dosyasında bir sınıfı genişleten bir sınıfa ve B dosyasında A dosyasında bir sınıfı genişleten bir sınıfa ihtiyacımız vardır. Bu olasılık düşük olsa da Guava'nın kod tabanında (ve başka yerlerde) gerçekleşir.

Bu sorunun doğal bir çözümü, .java dosyasında karşılaşılan her Java türü için ayrı bir üstbilgi dosyası yayınlamaktır. Ancak J2ObjC, derleme aracı olarak kullanılmak üzere tasarlanmıştır ve iyi bir derleme sistemi her giriş için tahmin edilebilir çıkışlara dayanır. Yani her .java dosyasının tam olarak bir .h ve bir .m dosyası oluşturması gerekir.

Örnek

Foo.java:

class Foo extends Bar {}

Bar.java:

class Bar {
  static class Baz extends Foo {}
}

Foo.h (segmentlere ayrılmamış):

#ifndef _Foo_H_
#define _Foo_H_

#include "Bar.h"
#include "J2ObjC_header.h"

@interface Foo : Bar
- (instancetype)init;
@end

#endif // _Foo_H_

Bar.h (segmentlere ayrılmamış):

#ifndef _Bar_H_
#define _Bar_H_

#include "Foo.h"
#include "J2ObjC_header.h"

@interface Bar : NSObject
- (instancetype)init;
@end

@interface Bar_Baz : Foo
- (instancetype)init;
@end

#endif // _Bar_H_

Foo.h'nın Bar.h'yi, Bar.h'nın ise Foo.h'yı içerdiğine dikkat edin. Sonuç olarak aşağıdaki üstbilgiler derlenemez:

../dist/j2objcc -c Foo.m
In file included from Foo.m:6:
In file included from ./Bar.h:9:
./Foo.h:12:18: error: cannot find interface declaration for 'Bar', superclass of 'Foo'
@interface Foo : Bar
~~~~~~~~~~~~~~   ^

Foo.h ve Bar.h dosyalarının hatasız derlenecek segmentlere ayrılmış sürümleri:

Foo.h (segmentlere ayrılmış):

#include "J2ObjC_header.h"

#pragma push_macro("Foo_INCLUDE_ALL")
#if Foo_RESTRICT
#define Foo_INCLUDE_ALL 0
#else
#define Foo_INCLUDE_ALL 1
#endif
#undef Foo_RESTRICT

#if !defined (_Foo_) && (Foo_INCLUDE_ALL || Foo_INCLUDE)
#define _Foo_

#define Bar_RESTRICT 1
#define Bar_INCLUDE 1
#include "Bar.h"

@interface Foo : Bar
- (instancetype)init;
@end

#endif

#pragma pop_macro("Foo_INCLUDE_ALL")

Bar.h (segmentlere ayrılmış):

#include "J2ObjC_header.h"

#pragma push_macro("Bar_INCLUDE_ALL")
#if Bar_RESTRICT
#define Bar_INCLUDE_ALL 0
#else
#define Bar_INCLUDE_ALL 1
#endif
#undef Bar_RESTRICT

#if !defined (_Bar_) && (Bar_INCLUDE_ALL || Bar_INCLUDE)
#define _Bar_

@interface Bar : NSObject
- (instancetype)init;
@end

#endif

#if !defined (_Bar_Baz_) && (Bar_INCLUDE_ALL || Bar_Baz_INCLUDE)
#define _Bar_Baz_

#define Foo_RESTRICT 1
#define Foo_INCLUDE 1
#include "Foo.h"

@interface Bar_Baz : Foo
- (instancetype)init;
@end

#endif

#pragma pop_macro("Bar_INCLUDE_ALL")