يتم تقسيم ملفات الرؤوس التي تم إنشاؤها باستخدام J2ObjC إلى أقسام ويمكن تضمين ملف واحد في كل مرة. يتم إنشاء شريحة واحدة لكل نوع Java مترجم، لذا سيكون لكل فئة داخلية شريحة خاصة بها. تُستخدَم وحدات الماكرو في المعالج المُسبَق لإخبار المُجمِّع بقراءة جزء معيّن فقط عند تضمين العنوان. تعمل عناوين المقسّمة على حلّ مشكلة دورات التضمين في العناوين التي تم إنشاؤها باستخدام J2ObjC، وهذه المشكلة موضّحة بالتفصيل في هذا المستند.
معلومات يجب معرفتها
- استخدِم
#include
بدلاً من#import
لتضمين العناوين التي تم إنشاؤها باستخدام J2ObjC.- يتسبب استخدام
#import
مع العناوين المقسّمة في حدوث مشاكل لأنّ المُجمِّع سيتخطّى قراءة العنوان إذا سبق له الاطّلاع عليه. ولكن بما أنّه تم تقسيم العنوان، قد لا يكون المُجمِّع قد حلّله بالكامل في المرة الأولى.
- يتسبب استخدام
- يمكن إيقاف العناوين المقسّمة باستخدام العلامة
--no-segmented-headers
.
المحتوى الذي يتضمّنه القسم "الرسائل الدائرية"
يجب أن تستخدم ملفات الرأس التي تم إنشاؤها باستخدام J2ObjC عمليات تضمين وإعلانات مُسبقة لتحديد معلومات النوع اللازمة. يتم استخدام التعريفات المُسبَقة قدر الإمكان، ومع ذلك، فإنّ عمليات التضمين ضرورية للأنواع التي يتم تمديدها أو تنفيذها، لأنّ المُجمِّع يتطلّب تعريف النوع الكامل.
من الممكن إنشاء دورات تضمين في ملفات الرأس التي تم إنشاؤها باستخدام J2ObjC. للحصول على دورة مماثلة، نحتاج إلى فئة في الملف "أ" تُنشئ فئة في الملف "ب"، وفئة في الملف "ب" تُنشئ فئة في الملف "أ". هذا سيناريو غير محتمل، ولكنه يحدث في قاعدة بيانات Guava (وفي أماكن أخرى).
قد يكون الحلّ الطبيعي لهذه المشكلة هو إنشاء ملف عنوان منفصل لكل نوع Java تم العثور عليه في ملف .java. ولكن تم تصميم J2ObjC لاستخدامه كأحد أدوات الإنشاء، ويعتمد أي نظام إنشاء جيد على النتائج المتوقّعة لكل مدخل. وهذا يعني أنّه من الضروري أن ينتج كل ملف بتنسيق .java ملفًا واحدًا بتنسيق .h وملفًا واحدًا بتنسيق .m.
مثال
Foo.java:
class Foo extends Bar {}
Bar.java:
class Bar {
static class Baz extends Foo {}
}
Foo.h (غير مقسَّم):
#ifndef _Foo_H_
#define _Foo_H_
#include "Bar.h"
#include "J2ObjC_header.h"
@interface Foo : Bar
- (instancetype)init;
@end
#endif // _Foo_H_
Bar.h (غير مقسّم):
#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 يتضمّن ملف Bar.h وملف Bar.h يتضمّن ملف Foo.h. ونتيجةً لذلك، يتعذّر تجميع هذين الملفَّين الرأسيين:
../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 وBar.h، والتي سيتم تجميعها بدون خطأ:
Foo.h (مقسّمة):
#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 (مقسّمة):
#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")