XB_RunLoop

1.RunLoop对象

iOS中有两套API来访问和使用RunLoop

Core Foundation框架:CFRunLoopRef,是开源的

Foundation框架:NSRunLoop,基于CFRunLoopRef的一层OC包装

2.获取RunLoop对象

[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象

CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象

[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象

CFRunLoopGetMain(); // 获得主线程的RunLoop对象

3.RunLoop相关的类

CFRunLoopRef 、CFRunLoopModeRef、CFRunLoopSourceRef 、CFRunLoopTimerRef 、CFRunLoopObserverRef

  • CFRunLoopModeRef

    1>CFRunLoopModeRef代表RunLoop的运行模式

    2> 一个RunLoop包含若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer

    3>RunLoop启动时只能选择其中一个Mode,作为currentMode

    4>如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入,  不同组的Source0/Source1/Timer/Observer能分隔开            来,互不影响

    5>如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出

  • CFRunLoopModeRef

    常见的两种Mode:

    1>kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行

    2>UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

  • CFRunLoopObserverRef

  

添加Observer监听RunLoop的所有状态 

4.RunLoop运行逻辑

  • Source0

    1>触摸事件处理

    2>performSelector:onThread:

  •  Source1

    1>基于Port的线程间通信

    2>系统事件捕捉

  • Timers

    1>NSTimer

    2>performSelector:withObject:afterDelay:

  • Observers

    1.用于监听RunLoop的状态,比如UI刷新和AutoreleasePool释放有可能在BeforeWaiting的时候。

  • RunLoop整个运行逻辑

     01、通知Observers:进入Loop

     02、通知Observers:即将处理Timers

     03、通知Observers:即将处理Sources

     04、处理Blocks 05、处理Source0(可能会再次处理Blocks)

     06、如果存在Source1,就跳转到第8步

     07、通知Observers:开始休眠(等待消息唤醒)

     08、通知Observers:结束休眠(被某个消息唤醒)

           01> 处理Timer

           02> 处理GCD Async To Main Queue

           03> 处理Source1

      09、处理Blocks

      10、根据前面的执行结果,决定如何操作

           01> 回到第02步

           02> 退出Loop

        11、通知Observers:退出Loop

RunLoop休眠的实现原理:

是由用户态切换到内核态实现休眠,用户态只能处理应用层,内核层面的api可以达到线程休眠,while(1)是用户态下的线程阻塞,但是线程没有休眠

<think>嗯,用户遇到了JavaFX应用程序启动时的几个错误:Unsupported JavaFX configuration、NoSuchMethodError和NullPointerException。我需要先理清每个错误可能的原因,然后给出相应的解决方案。 首先,Unsupported JavaFX configuration可能和JavaFX库的配置有关。根据引用3,如果主类没有正确扩展Application类或者main方法缺失,可能会引发配置问题。用户需要检查主类是否继承自javafx.application.Application,或者是否有正确的main方法。另外,Java 11之后,JavaFX需要作为独立库引入,所以项目配置是否正确也很重要,比如是否添加了模块路径或者依赖管理工具如Maven/Gradle的配置。 接下来是NoSuchMethodError,这通常是因为版本不兼容或依赖冲突。例如,引用的某个类库中的方法在运行时版本中不存在。用户需要确认使用的JavaFX版本是否一致,所有模块是否正确添加到模块路径,并且检查是否有其他依赖库与JavaFX冲突。比如,如果用户升级了JavaFX版本,但遗留的旧库还在classpath中,就可能出现这个问题。 然后是NullPointerException,可能由资源路径错误或未正确初始化组件引起。引用5提到,Location is required错误通常是因为FXML文件路径不正确,或者未正确使用getResource方法加载资源。用户需要检查FXML文件的路径是否正确,以及加载资源时是否使用了相对路径,并且确保在构建时资源文件被正确打包。 另外,引用4提到了在JavaFX应用线程中更新UI组件的问题,但用户的问题可能更多是启动时的错误,所以可能需要关注初始化阶段的线程安全,但暂时可能不是主因。不过,Platform.runLater的使用可能在其他部分需要检查。 综合这些引用和常见问题,解决方案应该包括:检查主类和main方法配置、确保JavaFX库正确引入、检查依赖版本一致性、验证资源路径正确性。此外,用户可能需要使用--add-modules参数来启用JavaFX模块,特别是在命令行或IDE配置中添加这些参数。如果使用IDE如IntelliJ,还需要检查运行配置是否正确,模块路径是否包含所有必要的JavaFX SDK库。 可能需要分步骤指导用户:首先检查主类结构,然后确认依赖配置,接着检查资源路径,最后处理可能的模块化和JVM参数。同时,根据引用5的方案,可能需要将资源文件标记为Resources Root,或者使用绝对路径加载FXML。 最后,生成相关问题时要涵盖常见的配置错误、依赖管理、资源加载和线程问题,帮助用户全面排查可能的问题点。</think>### JavaFX启动错误解决方案 #### 一、错误原因分析 1. **Unsupported JavaFX configuration** - 通常因主类未正确继承$Application$类或缺失$main()$方法导致[^3] - 使用模块化系统时未正确配置$module-info.java$ 2. **NoSuchMethodError** - 不同版本的JavaFX组件存在API差异 - 依赖库版本冲突(例如同时存在JavaFX 11和JavaFX 8的jar包) 3. **NullPointerException** - FXML文件路径配置错误或资源未正确加载[^5] - 未初始化UI组件直接调用其方法 #### 二、分步解决方案 **步骤1:验证主类结构** 主类必须满足以下任一条件: ```java // 方式一:继承Application类 public class Main extends Application { public static void main(String[] args) { launch(args); } } // 方式二:独立main方法显式启动 public class Main { public static void main(String[] args) { Application.launch(MyApp.class, args); } } ``` **步骤2:配置模块化系统(Java 9+)** 在$module-info.java$中添加: $$module your.module { requires javafx.controls; requires javafx.fxml; opens your.package to javafx.graphics; }$$ 通过VM参数指定模块路径: `--module-path /path/to/javafx-sdk/lib --add-modules=javafx.controls,javafx.fxml` **步骤3:检查依赖一致性** 使用Maven/Gradle时确保版本统一: ```xml <!-- Maven示例 --> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>17.0.2</version> </dependency> ``` **步骤4:修正资源加载方式** 使用绝对路径加载FXML: ```java Parent root = FXMLLoader.load(getClass().getResource("/com/example/view/main.fxml")); ``` 确保资源目录被标记为*Resources Root*(IDEA中右键目录设置) **步骤5:线程安全操作** 在非JavaFX线程更新UI时使用: ```java Platform.runLater(() -> { label.setText("更新内容"); }); ``` [^4] #### 三、典型错误场景 1. **命令行启动报错** 完整启动命令示例: `java --module-path /javafx-sdk/lib --add-modules=javafx.controls -jar your-app.jar` 2. **IDE配置问题** IntelliJ中需设置: - Run/Debug Configurations → VM options添加模块参数 - Project Structure → Libraries添加JavaFX SDK路径 3. **模块化与非模块化混用** 非模块化项目需将所有JavaFX jar包添加到classpath
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值