קובצי הכותרות שנוצרו על ידי J2ObjC מחולקים לפלחים, וניתן לכלול פלג אחד בכל פעם. נוצר פלח אחד לכל סוג Java מתורגם, כך שלכל כיתה פנימית יהיה פלח משלה. מאקרו של מעבד מקדים משמש כדי להורות למהדר לקרוא רק קטע מסוים כשהוא כולל את הכותרת. כותרות מחולקות פותרות את הבעיה של מחזורי include בכותרות שנוצרו על ידי J2ObjC, כפי שמתואר בפירוט במסמך הזה.
מה כדאי לדעת
- כדי לכלול כותרות שנוצרו על ידי J2ObjC, משתמשים ב-
#include
במקום ב-#import
.- שימוש ב-
#import
עם כותרות מחולקות הוא בעייתי, כי המהדר ידלג על קריאת הכותרת אם הוא כבר ראה אותה. עם זאת, מכיוון שהכותרת מחולקת לקטעים, יכול להיות שהמבקר לא ניתח אותה במלואה בפעם הראשונה.
- שימוש ב-
- אפשר להשבית כותרות מחולקות באמצעות הדגל
--no-segmented-headers
.
מה כלול במבצע המעגלי
קובצי הכותרת שנוצרו על ידי J2ObjC חייבים להשתמש בהכללות ובהצהרות מעבר כדי לפתור את פרטי הסוגים הנדרשים. אנחנו משתמשים בהצהרות עתידיות ככל האפשר, אבל יש צורך ב-include לסוגים שמתרחבים או מיושמים, כי המהדר צריך את הצהרת הסוג המלאה.
אפשר ליצור מחזורי include בקובצי הכותרת שנוצרו על ידי J2ObjC. כדי ליצור מחזור כזה, צריך שיהיה בכיתה בקובץ A שמייצגת את הכיתה בקובץ B, וכיתה בקובץ B שמייצגת את הכיתה בקובץ A. זהו תרחיש לא סביר, אבל הוא מתרחש בקוד של Guava (ובמקומות אחרים).
פתרון טבעי לבעיה הזו יכול להיות הפקת קובץ כותרת נפרד לכל סוג Java שנמצא בקובץ .java. אבל J2ObjC מיועד לשימוש ככלי build, וכל מערכת build טובה מסתמכת על פלט צפוי לכל קלט. כלומר, לכל קובץ .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. כתוצאה מכך, ה-header האלה לא עוברים קומפילציה:
../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")