【问题标题】:Generate with public instead of private members with j2objc使用 j2objc 使用公共而不是私有成员生成
【发布时间】:2016-01-25 13:47:15
【问题描述】:

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

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

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

我使用类似于here (in documentation) 描述的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)

感谢您的帮助和建议。

【问题讨论】:

    标签: java j2objc


    【解决方案1】:

    --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 文件添加相同的类类别,只要它们没有区别。但是,我还没有验证这是否有效,因为“私有字段不应该被外部类访问!” :-)

    【讨论】:

    • Tom - 去掉标志怎么样?这样,当构建更新时,自然会迫使某人意识到更改。此外,它还允许您删除可能会长期存在的垃圾。
    • 汤姆,感谢您的解释。所以我明白了,我不得不打扰 Java 开发人员采用他们的代码来满足我当前的需求。
    【解决方案2】:

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

    error: instance variables may not be placed in class extension
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-03
      • 2013-10-10
      • 1970-01-01
      相关资源
      最近更新 更多