سرصفحه های تقسیم شده

فایل‌های هدرهای تولید شده J2ObjC به بخش‌هایی تقسیم می‌شوند و می‌توان آن‌ها را در یک بخش در یک زمان گنجاند. یک بخش برای هر نوع جاوا ترجمه شده ایجاد می شود، بنابراین هر کلاس داخلی سگمنت مخصوص به خود را خواهد داشت. ماکروهای پیش پردازنده برای اینکه به کامپایلر بگوییم که فقط یک بخش خاص را در هنگام گنجاندن هدر بخواند استفاده می شود. هدرهای قطعه بندی شده مشکل چرخه های شامل در هدرهای تولید شده J2ObjC را حل می کند که در زیر به تفصیل شرح داده شده است.

چه چیزی میخواهید بدانید

  • #include به جای #import برای اضافه کردن هدرهای تولید شده J2ObjC استفاده کنید.
    • استفاده از #import با هدرهای قطعه بندی شده مشکل ساز است زیرا کامپایلر در صورتی که هدر را قبلا دیده باشد از خواندن آن صرفنظر می کند. اما، از آنجایی که هدر قطعه بندی شده است، ممکن است بار اول به طور کامل توسط کامپایلر تجزیه نشده باشد.
  • هدرهای تقسیم شده را می توان با پرچم --no-segmented-headers غیرفعال کرد.

دایره شامل

فایل‌های هدر تولید شده J2ObjC باید از اعلان‌های شامل و فوروارد برای حل اطلاعات نوع ضروری استفاده کنند. اعلان‌های فوروارد تا حد امکان مورد استفاده قرار می‌گیرند، با این حال شامل مواردی است که برای توسعه یا پیاده‌سازی انواع ضروری است زیرا کامپایلر به اعلان نوع کامل نیاز دارد.

امکان تولید چرخه های شامل در فایل های هدر تولید شده J2ObjC وجود دارد. برای بدست آوردن چنین چرخه ای، ما به یک کلاس در فایل A نیاز داریم که یک کلاس را در فایل B گسترش می دهد، و یک کلاس در فایل B که یک کلاس را در فایل A گسترش می دهد. این یک سناریوی بعید است، اما در پایگاه کد Guava (و جاهای دیگر) رخ می دهد. ).

یک راه حل طبیعی برای این مشکل ممکن است انتشار یک فایل هدر مجزا برای هر نوع جاوا باشد که در فایل جاوا. اما 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")