gpt4 book ai didi

ios - RoboVM 中非常奇怪的 NullPointerException

转载 作者:行者123 更新时间:2023-11-29 01:57:33 25 4
gpt4 key购买 nike

如果我使用任何非空参数调用以下 RoboVM 方法:

public static void runOnUiThread(final Runnable runnable) {
System.out.println("Inside runOnUiThread():");
System.out.println(" Null-check: "+(runnable==null));

NSOperation operation = new NSOperation() {

@Override
public void main() {
System.out.println("Inside main():");
System.out.println(" Null-check: "+(runnable==null));
runnable.run(); // NullPointerException here?!? How???
System.out.println(" main() completed");
}
};

NSOperationQueue.getMainQueue().addOperation(operation);
}

它输出:

Inside runOnUiThread():
Null-check: false
Inside main():
Null-check: true
java.lang.NullPointerException
at RoboVMTools$1.main(RoboVMTools.java)
at org.robovm.apple.foundation.NSOperation.$cb$main(NSOperation.java)
at org.robovm.apple.uikit.UIApplication.main(Native Method)
at org.robovm.apple.uikit.UIApplication.main(UIApplication.java)
at Main.main(Main.java)

这到底是怎么回事???更重要的是,我该如何解决这个问题?

  • 我尝试在 NSOperationQueue... 之前添加 operation.addStrongRef(runnable);。没有区别。
  • 我还尝试将匿名内部类移动到它自己的类中,该类有一个 private final 字段来存储传递给其构造函数的可运行对象。结果相同。

我是不是错过了一些完全明显的东西???

最佳答案

您对 GC 的看法是正确的。您的NSOperation在从 Objective-C 端调用操作之前,实例会被垃圾回收。当NSOperationQueue调用 Java 端 NSOperation 的新实例将创建匿名类,该类没有对 Runnable 的引用实例而是 null结果是 NullPointerException被抛出。

您使用 addStrongRef() 解决它的方式是正确的,尽管只有 mainQueue.addStrongRef(operation)和相应的removeStrongRef()电话应该足够了:

public static void runOnUiThread(final Runnable runnable) {

final NSOperationQueue mainQueue = NSOperationQueue.getMainQueue();

NSOperation operation = new NSOperation() {

@Override
public void main() {
runnable.run();
mainQueue.removeStrongRef(this);
}
};

mainQueue.addStrongRef(operation);
mainQueue.addOperation(operation);
}

这将阻止 Java operation实例(以及从它可访问的任何 Java 对象,如 Runnable )从被 GC 直到 Objective-C NSOperationQueue实例被释放。由于 Objective-C 端队列是一个单例,因此在应用程序的生命周期内不会被释放。

RoboVM NSOperationQueue Java 类提供了 addOperation() 的版本需要 Runnable 的方法。使用此方法时,RoboVM 将负责保留 Runnable实例,而 Objective-C 方面需要它。对于任何采用 @Block 的方法也是如此。 Runnable 类型的带注释参数或 org.robovm.objc.block.VoidBlock* 中的任何一个或 org.robovm.objc.block.Block*接口(interface)。

使用这个addOperation()方法你的代码简单地变成:

public static void runOnUiThread(Runnable runnable) {
NSOperationQueue.getMainQueue().addOperation(runnable);
}

附言。 RoboVM 使用的 GC 与 Apple 垃圾收集器无关,因此 Apple 的文档无法帮助您理解此类问题。

关于ios - RoboVM 中非常奇怪的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30688370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com