0

我最近将 j2objc 从 0.9.4 更新到最新版本 (0.9.8.2.1)。以前的版本将所有成员都生成为公共成员,但从 0.9.6 开始,私有成员默认是隐藏的。由于某些原因,我必须访问其他类的一些私有成员。发行说明中有一个解决方案:

注意: --hide-private-members 现在是默认值,因此私有字段和方法在公共头文件中不再可见。如果这破坏了您的项目,请修复非法引用,使这些成员非私有(因为它们不是),或使用 --no-hide-private-members 标志。

我试图将此标志附加到我的项目中,但没有成功(我无法更改 java 代码)。我试过阅读j2objc --help,但没有提到这个标志。所以我想知道我在哪里设置了这个标志来像以前一样与所有公共成员一起构建项目?

我使用类似于此处描述的 makefile(在文档中)。这是它的一部分:

default: translate cycle_finder

clean:
    @rm -rf $(BUILD_DIR)
    @rm -rf $(J2OBJC_RESULT_DIR)
    @rm -f $(RETAIN_CYCLES)

$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.m
    $(J2OBJCC) -I$(BUILD_DIR) -c $? -o $@

translate: pre_translate $(J2OBJC_GENERATED_SOURCES)
    @if [ `cat $(JAVA_SOURCES) | wc -l` -ge 1 ] ; then \
      ./build_mappings.pl $(CALCULATOR_NEUTRAL_DIR) CN > $(JAVA_PACKAGE_MAPPINGS); \
      ./build_mappings.pl $(FOUNDATION_NEUTRAL_DIR) FN >> $(JAVA_PACKAGE_MAPPINGS); \
      ./build_mappings.pl $(CALCULATOR_NEUTRAL_TEST_DIR) CNT >> $(JAVA_PACKAGE_MAPPINGS); \
      ./build_mappings.pl $(FOUNDATION_NEUTRAL_TEST_DIR) FNT >> $(JAVA_PACKAGE_MAPPINGS); \
      $(J2OBJC) \
        --no-hide-private-members \
        -sourcepath $(SOURCE_DIR) \
        $(ADDITIONAL_CLASS_PATHS) -use-arc  \
        -d $(J2OBJC_RESULT_DIR) \
        --prefixes $(JAVA_PACKAGE_MAPPINGS) \
        `cat $(JAVA_SOURCES)` ; \
    fi

cycle_finder: pre_translate $(J2OBJC_GENERATED_SOURCES)
    -@if [ `cat $(JAVA_SOURCES) | wc -l` -ge 1 ] ; then \
      $(CYCLE_FINDER) \
        --no-hide-private-members \
        -sourcepath $(SOURCE_DIR) \
        -w $(WHITELIST_PATH) \
        $(ADDITIONAL_CLASS_PATHS) \
        `cat $(JAVA_SOURCES)` > $(RETAIN_CYCLES); \
    fi

$(J2OBJC_RESULT_DIR):
    @mkdir -p $(J2OBJC_RESULT_DIR)

$(BUILD_DIR):
    @mkdir -p $(BUILD_DIR)

pre_translate: $(J2OBJC_RESULT_DIR) $(BUILD_DIR)
    @rm -f $(JAVA_SOURCES)
    @touch $(JAVA_SOURCES)

$(J2OBJC_RESULT_DIR)/%.m $(J2OBJC_RESULT_DIR)/%.h: $(SOURCE_DIR)/%.java JavaBuild.make
    @echo $< >> $(JAVA_SOURCES)

感谢您的任何帮助和建议。

4

2 回答 2

0

--no-hide-private-members标志只是为项目提供一些时间来更新其访问权限的临时标志,并且两年多前发布了 0.9.4。该标志存在以允许构建仍然工作,但现在被忽略。

一般来说,私有字段不应该被外部类访问,不管它们是用什么语言编写的。起初我们天真地假设本地开发人员会遵守在翻译代码中声明的访问,但我们发现 Xcode 的代码完成使用私有成员太诱人了。现在私有字段、方法和类现在都隐藏在 .m 文件中。

也就是说,没有什么可以阻止您绕过访问限制。要在 Java 中做到这一点(它也应该在 Android 上工作):

Field f = TargetClass.class.getDeclaredField("privateField");
f.setAccessible(true);
// read or write f using reflection

要在本地执行此操作,您可以尝试将目标类生成的 .m 文件(声明该字段的位置)中的类类别复制到您的本地文件中。AFAIK,没有什么可以阻止多个 .m 文件添加相同的类类别,只要它们没有区别。但是,我还没有验证这是否有效,因为“私有字段不应该被外部类访问!” :-)

于 2015-10-26T18:00:22.407 回答
0

问题是 j2objc 生成无效的 Objective-C 代码。所有私人 ivars 都不能属于一个类别,您最终会得到

error: instance variables may not be placed in class extension

对于您拥有的每个私有 java 变量。

有时代码是第 3 方,我们无法更新访问权限。

于 2016-01-20T18:18:51.173 回答