iOS问题记录 - Xcode 15安装低版本iOS模拟器(持续更新)
文章目录
- 前言
- 开发环境
- 问题描述
- 问题分析
- 1. 定位问题
- 2. 逆向分析
- 2.1. IDA Free
- 2.2. Hopper Disassembler Demo
- 3. 模拟器日志
- 4. supportedArchs
- 解决方案
- 最后
前言
最近新需求很多,项目改动很大,开发完成后想测一遍在低版本iOS系统上的兼容性,没想到低版本的iOS模拟器设备突然无法创建了。
在去年年底我研究过这个问题,写下了这篇文章iOS问题记录 - Xcode 14安装低版本iOS模拟器(持续更新),虽然当时没有完全解决,但暂时也够用,没想到现在这个问题又出现了。如果还没有阅读过这篇文章,强烈建议先阅读这篇前置文章。
这里先说明一下,虽然标题是Xcode 15安装低版本iOS模拟器,但是在遇到这个问题时Xcode 15还处于Beta版,平时还是以Xcode 14.3.1版本为主,至于标题中为什么用Xcode 15,请继续往下看。
开发环境
- macOS: 13.4
- Xcode: 14.3.1 / 15 beta 5
问题描述
在Xcode 14.3.1版本中,低版本iOS模拟器文件已经修改了Info.plist
文件中的CFBundleIdentifier
属性值,但是创建iOS模拟器的时候却还是无法选择。从官网重新下载Xcode 14.0.1版本创建低版本iOS模拟器,还是无法选择无法创建,最低只能创建iOS 14.0.1模拟器。
问题分析
1. 定位问题
首先怀疑是不是Xcode 14.3.1版本又加了其他限制,导致原先的方法失效。找了一台打包机,将Xcode版本升到14.3.1,尝试创建低版本iOS模拟器,一切正常!这是怎么回事?
这就不得不提CoreSimulator
框架,文件位于/Library/Developer/PrivateFrameworks/CoreSimulator.framework
,Xcode的模拟器管理靠它来实现。现在Xcode版本一致,却出现一个正常一个不正常,难道是CoreSimulator
框架版本不一致?
查看CoreSimulator
框架版本的两种方法:
- 通过命令查看
xcrun simctl --version
执行输出:
@(#)PROGRAM:simctl PROJECT:CoreSimulator-917
simctl
是用于管理和控制模拟器的命令行工具,更多用法可以通过xcrun simctl help
命令查看。
- 通过
version.plist
文件查看
找到CoreSimulator
框架文件(前面有写路径),version.plist
文件位于Versions/A/Resources
目录路径下。
经过对比发现,我电脑上的版本是917
,而打包机上的版本是885.2
。咦🤔?这版本什么️时候升级的我怎么不知道。思来想去,很可能是在前几天体验Xcode 15 beta 5版本的时候更新了CoreSimulator
框架。打开大版本更新的Xcode时,一般都会弹出一个安装界面,然后请求管理员权限安装其他组件:
这时候就会自动更新CoreSimulator
框架,当然也不限于这个框架,还有其他一些组件也会更新。
接下来就是验证是不是因为CoreSimulator
框架版本不一致导致的问题,最简单的验证方法是将917
版本降回885.2
版本,然后再测试能否创建低版本iOS模拟器。我本来打算先将已有的CoreSimulator
框架文件删除,然后从打包机复制一份到原路径,结果刚删除立马就弹出这个:
允许操作后自动重新安装了885.2
版本的CoreSimulator
框架,用Xcode 14.3.1版本实测可以创建iOS 12.0版本的模拟器,同时运行与调试也一切正常。
由此可以确定当前问题是CoreSimulator
框架升级版本后导致的,那么该怎么解决呢?如果是Xcode 14遇到这个问题,直接删除新版本的CoreSimulator
框架然后自动重装老版本即可(如果没有自动重装,重新打开Xcode 14也可以完成安装)。不过,这治标不治本,后面Xcode 15还是无法创建低版本iOS模拟器。
2. 逆向分析
CoreSimulator
框架的核心是Versions/Current/CoreSimulator
可执行文件,想知道框架升级改了什么导致了当前问题的话,逆向分析这个可执行文件是最快的方式。
以下所使用的逆向工具虽然是免费版本,但是如果不开代理可能下载很慢,这里提供分享链接,希望能对你有所帮助。
- 百度网盘
2.1. IDA Free
关于逆向工具,我首选的是IDA Pro的免费版IDA Free,虽然功能受限,但是基本的静态分析是可用的,最重要的是免费。需要特别注意的一点是IDA Free被限制了只能处理x86/x64
架构的二进制文件,这对CoreSimulator
可执行文件不是问题,通过file
命令可以知道这个可执行文件是个Mach-O
通用二进制文件,包含了x86_64
架构。
file /Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/CoreSimulator
执行输出:
/Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/CoreSimulator: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64e]
/Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/CoreSimulator (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
/Library/Developer/PrivateFrameworks/CoreSimulator.framework/Versions/A/CoreSimulator (for architecture arm64e): Mach-O 64-bit dynamically linked shared library arm64e
建议复制一份CoreSimulator
可执行文件到其他目录用于静态分析,用IDA Free打开时选择x86_64
架构文件:
当底部的消息输出窗口提示初始化自动分析已完成(“The initial autoanalysis has been finished.”)就可以开始进行静态分析。
万事开头难,现在该怎么找到问题所在呢?之前通过修改Info.plist
文件中的CFBundleIdentifier
属性值绕过了Xcode的限制,那说明CoreSimulator
可执行文件很可能内置了各个模拟器版本的CFBundleIdentifier
值用于判断,以此为切入口或许能找到新增加的限制判断。
通过快捷键Shift + Fn + F12
或[菜单栏 View] -> [Open subviews] -> [Strings]打开字符串窗口,然后快捷键Command + F
搜索关键词com.apple.CoreSimulator.SimRuntime.iOS-
:
选择任意一个搜索结果双击来到IDA View窗口,通过快捷键X
查看引用:
结果没什么用,定位不了在哪里被引用。只好换个思路,从可能相关的函数入手。结合函数列表和模拟器文件的名称(iOS xx.x.simruntime
),基本可以确定要找的函数应该和SimRuntime
(模拟器运行时)相关。
从这些函数(方法)名可以看出CoreSimulator
框架应该是用Objective-C
开发的,一般首次加载文件时会弹框提示检测到Objective-C
结构,询问是否要解析并重命名方法,以上的方法名经过了解析处理。看方法命名,严重怀疑-[SimRuntime isAvailableWithError:]
方法就是我们要找的。在IDA View窗口使用快捷键Fn + F5
查看该方法的伪代码:
相对于汇编代码,伪代码可读性确实高了些,方法调用(objc_msgSend
)一目了然。不过一些引用数据,特别是字符串没有直接将指针转为实际指向的内容,例如&off_D9D70
指针,需要点进去才知道指向的内容是arm64
字符串,这导致阅读和搜索(文本搜索快捷键Option + T
)伪代码都不方便。
分析一番,收获不大,尝试分析其他相关的方法,也没能找到问题所在。或许可以换个逆向工具试试?
2.2. Hopper Disassembler Demo
Mach-O
文件的常用逆向工具还有Hopper Disassembler,它的功能会比IDA Pro弱些,但是更易上手使用。Demo版本虽然功能受限,但是基本够用,唯一需要注意的一点是每次打开只能用30分钟,到时间会弹框强制关闭。
打开Hopper Disassembler,点击Try the Demo
开始使用。将需要分析的文件拖进去,会出现弹框:
这里没有被限制只能处理x86/x64
架构的二进制文件,可以任选选择。等待自动分析完成就可以开始静态分析,详细使用教程请参考官方教程。
相比IDA Free的伪代码,这个的可读性确实更高些。不过分析一番还是没能找到问题所在,难道只能暂时搁置了?
3. 模拟器日志
如果能向分析源码一样,随时能打印日志和调试断点,逆向分析就轻松了。对于修改和调试二进制文件,前面的逆向工具也不是不能做,只是比较麻烦,而且这些功能在免费版上基本受限用不了。
正当我考虑要不要暂时搁置问题的时候,灵光一闪,日志可能一直都存在!在静态分析中经常能看到日志打印:
而且日志打印好像也没什么限制,猜测应该是一直在输出:
通常日志会被写入文件系统(.log
扩展名的文件),那这些日志被输出到哪了呢?尝试搜索.log
字符串查找写入文件路径:
%s/Library/Logs/CoreSimulator/CoreSimulator.%s.log
应该就是日志文件的路径,不过这路径前面部分的%s
还不确定。在汇编显示模式下点击指定行,然后点击右键就可以查看相关引用:
日志文件路径被____SimLogASLInit_block_invoke
函数引用了,从伪代码可知路径前面部分的%s
是被环境变量HOME
的值替换了:
执行env
命令打印环境变量可知,HOME
变量的值是用户目录路径,例如/Users/xxx
,所以模拟器日志文件所在目录的完整路径是/Users/xxx/Library/Logs/CoreSimulator
。打开该目录下的CoreSimulator.log
文件,发现一直在打印这样的错误日志:
Aug 9 21:36:53 mac com.apple.CoreSimulator.simctl[30026] <Error>: Error Domain=com.apple.CoreSimulator.SimError Code=401 "Unable to determine supported architectures for runtime (/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime)" UserInfo={NSLocalizedDescription=Unable to determine supported architectures for runtime (/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime)}
难道这个报错日志是问题的关键?将CoreSimulator
框架版本降为885.2
后,不再打印类似的错误日志。
补充一点:后续通过逆向发现CoreSimulator.log
日志文件实际应该是CoreSimulator
框架下的Versions/A/Resources/bin/simctl
生成的,不过以上报错的关键信息确实来源于CoreSimulator
可执行性文件。
4. supportedArchs
逆向CoreSimulator
可执行文件,搜索关键词Unable to determine supported architectures for runtime
,通过相关引用定位到-[SimRuntime initWithBundle:error:]
方法:
相关伪代码(省略部分):
loc_9658b:rax = [r15 objectForKeyedSubscript:@"supportedArchs"];rax = [rax retain];var_268 = rax;if (rax != 0x0) {...}else {rax = (r14)(@class(NSBundle), @selector(bundleWithIdentifier:), @"com.apple.CoreSimulator");rax = [rax retain];rbx = rax;r15 = @"Unable to determine supported architectures for runtime (%@)";rdx = r15;rcx = r15;rax = (r14)(rax, @selector(localizedStringForKey:value:table:), rdx, rcx, 0x0);rax = [rax retain];r12 = rax;if (rax != 0x0) {r15 = rax;}rax = (r14)(var_218, @selector(bundlePath), rdx, rcx, 0x0);rax = [rax retain];r15 = [(r14)(@class(NSString), @selector(stringWithFormat:), r15, rax, 0x0) retain];[rax release];[r12 release];[rbx release];var_208 = r15;rax = [NSError errorWithSimErrno:0x191 localizedDescription:r15];rax = [rax retain];if (rax != 0x0) {__SimLog(0x3, "-[SimRuntime initWithBundle:error:]", 0x1fa, @"%@", rax, r9, var_3C0);rax = rax;}r14 = var_1E8;r15 = var_1F0;rbx = var_238;if (r14 != 0x0) {rax = objc_retainAutorelease(rax);*r14 = rax;}r12 = 0x0;r14 = var_1C0;}...
逆向885.2
版本的CoreSimulator
可执行文件,对比同个方法的伪代码,这部分判断逻辑确实是新加的。从以上伪代码可知,r15
(根据objectForKeyedSubscript
可以推测应该是NSDictionary
类型)通过supportedArchs
键获取对应值时,因为键不存在所以返回NULL
(也就是0x0
),进而执行else
代码块打印错误日志。那么r15
的值是从哪来的呢?
通过不断溯源查找应该可以找到,不过这个方法的伪代码很长,需要耗费不少时间精力。换个思路,根据报错信息中出现的模拟器文件路径(/Library/.../Runtimes/iOS 12.4.simruntime
)以及发生错误的方法(-[SimRuntime initWithBundle:error:]
),可以大胆猜测错误是在加载模拟器文件初始化SimRuntime
对象时发生的,所以r15
的值很可能源于模拟器文件中的某个配置文件。
搜索关键词plist
查找可能的配置文件:
咦🤔️?这行rax = [r12 pathForResource:@"profile" ofType:@"plist"];
代码获取了profile.plist
文件的完整路径,感觉很有可能就是它。找到iOS 12.4.simruntime
文件,右键显示包内容,然后搜索profile.plist
,搜索结果如下:
打开后确实没找到supportedArchs
属性。另找一个没报错的模拟器文件,打开其中的profile.plist
文件,确实有该属性:
将iOS 12.4.simruntime
文件中的profile.plist
复制一份到其他地方,然后打开添加supportedArchs
属性并保存,最后将修改后的文件替换原来的文件。
重新打开Xcode创建低版本iOS模拟器,还是不行。难道这么做无效?再次检查一下模拟器日志还有没有报错,好吧,原先的错误没了,来了新的错误:
Aug 9 23:28:01 mac com.apple.CoreSimulator.simctl[30026] <Error>: Failed to setup launchHostClient for runtime com.apple.CoreSimulator.SimRuntime.iOS-12-4-1: Error Domain=NSPOSIXErrorDomain Code=88 "Malformed Mach-o file" UserInfo={NSLocalizedDescription=Failed to open liblaunch_sim: dlopen(/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/host/liblaunch_sim.dylib, 0x0101): tried: '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/host/liblaunch_sim.dylib' (fat file, but missing compatible architecture (have 'x86_64,i386', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/host/liblaunch_sim.dylib' (no such file), '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 12.4.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/host/liblaunch_sim.dylib' (fat file, but missing compatible architecture (have 'x86_64,i386', need 'arm64')), NSLocalizedFailureReason=Malformed Mach-o file}
关键报错信息:
but missing compatible architecture (have 'x86_64,i386', need 'arm64')
报错信息说的很明白,缺少arm64
架构。这些低版本的模拟器文件肯定是没有arm64
架构的,毕竟发布的时候arm
架构的M系列芯片还没出来。逐一查看电脑上已有的iOS模拟器文件,发现supportedArchs
属性是从iOS 14.0.simruntime
开始出现的,这就对了,iOS 14/Xcode 12/M1芯片都是2020年发布的,也就是说,当前问题只会出现在iOS 14以下。
看来不能完全照搬照抄,将supportedArchs
属性中的arm64
删除,重新打开Xcode创建低版本iOS模拟器,创建成功!不过尝试启动,却出现了弹框报错:
经过实测发现是模拟器相关的服务没有重启。模拟器服务CoreSimulatorService
是CoreSimulator
框架的一部分,用于管理模拟器的创建、启动、停止和删除等功能。打开活动监视器,找到com.apple.CoreSimulator.CoreSimulatorService
进程,然后结束进程。
重新运行iOS 12.4版本的模拟器,能启动但是黑屏。好吧,可用的低版本iOS模拟器又少了。实测iOS 13.7以下版本不是黑屏就是无法运行和调试应用,真是忙了个寂寞!明明Xcode 15的部署目标最低还是iOS 12,却不支持iOS 13.7以下的模拟器。以下来自官方支持文档:
文档中Xcode 14.3.1版本的iOS模拟器显示最低支持iOS 13.7,但实际可下载列表中最低版本已经是iOS 14.0.1。
解决方案
强烈建议先阅读前置文章iOS问题记录 - Xcode 14安装低版本iOS模拟器(持续更新),然后在修改Info.plist
文件的基础上,再额外修改模拟器文件中的profile.plist
(位于Contents/Resources
目录)文件,增加supportedArchs
属性,具体增加的内容如下:
注意事项:
- 建议先复制一份
profile.plist
文件到其他地方,修改完成后再替换原文件 - 如果遇到问题的iOS模拟器版本大等于iOS 14.0,那么应该不是同一个问题
- 实测Xcode 15 beta 5版本最低只支持iOS 13.7版本,而且可能因为配套使用的
Simulator.app
(Xcode内置)也还处于Beta版,运行调试会有点问题。 - 如果你还在用Xcode 14却遇到当前问题,建议按问题分析中的操作重装老版本的
CoreSimulator
框架
总的来说,如果Xcode 15正式版最低也只支持到iOS 13.7版本,那么后续想使用更低版本的iOS模拟器就只能通过Xcode 14。等正式版发布后,会重新测试并更新本篇文章。
以下是一些Xcode版本所支持的最低iOS模拟器版本:
最后更新日期:2023/08/10
Xcode version | CoreSimulator framework version | Minimum supported simulator version |
---|---|---|
14.0.1 | 857.7 | 12.0 |
14.2 | 857.14 | 12.0 |
14.3.1 | 885.2 | 12.0 |
15 beta 5 | 917 | 13.7 |
以上数据实测于M芯片的电脑,如果不是M芯片的电脑,可能会因为架构不一致有所差别。不过,更有可能是因为电脑上的Xcode版本和CoreSimulator
框架版本不一致导致的,当这两个版本不一致时以CoreSimulator
框架版本为主。
最后
如果这篇文章对你有所帮助,点赞👍加星🌟支持一下吧,谢谢~
本篇文章由@crasowas发布于CSDN。
相关文章:

iOS问题记录 - Xcode 15安装低版本iOS模拟器(持续更新)
文章目录 前言开发环境问题描述问题分析1. 定位问题2. 逆向分析2.1. IDA Free2.2. Hopper Disassembler Demo 3. 模拟器日志4. supportedArchs 解决方案最后 前言 最近新需求很多,项目改动很大,开发完成后想测一遍在低版本iOS系统上的兼容性,…...

高端百度地图开发2:自定义水滴头像(鼠标事件、API封装对接)
高端百度地图开发系列 高端百度地图开发1:自定义水滴头像(自定义标注覆盖物、Overlay覆盖类) 自定义水滴头像之鼠标事件、API封装对接 高端百度地图开发系列一、添加自定义覆盖物的方法二、对接API数据1.获取API数据(模拟)2.遍历数据3.添加自…...

R语言生存分析(机器学习)(2)——Enet(弹性网络)
弹性网络(Elastic Net):是一种用于回归分析的统计方法,它是岭回归(Ridge Regression)和lasso回归(Lasso Regression)的结合,旨在克服它们各自的一些限制。弹性网络能够同时考虑L1正则…...
【Docker】使用 Docker Registry 搭建自己的 Docker 镜像仓库
使用 Docker Registry 搭建自己的 Docker 镜像仓库 在使用 Docker 进行应用程序的开发和部署时,使用 Docker 镜像仓库是一个很好的实践。它允许集中存储和管理 Docker 镜像,方便团队协作和版本控制。在本文中,将介绍如何使用 Docker Registr…...
Spring 是什么框架?
Spring 是 Java EE 编程领域的一款轻量级的开源框架,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,它的目标就是要简化 Java 企业级应用程序的开发难度和周期。 Spring 自诞生以来备受青睐,一直被广大开发人员作为 Java 企业…...

Azure添加网络接口
添加网络接口的意义 在 Azure 上,为虚拟机添加网络接口的意义包括以下几个方面: 扩展网络带宽:通过添加多个网络接口,可以增加虚拟机的网络带宽,提高网络传输速度和数据吞吐量。实现网络隔离:每个网络接口…...

Linux 内核第一版 (v0.01) 开源代码解读
探索Linux v0.01的内部结构,Linux内核经常被认为是一个庞大的开源软件。在撰写本文时,最新版本是v6.5-rc5,包含36M行代码。不用说,Linux是几十年来许多贡献者辛勤工作的成果。 Linux 内核首个开源版本 (v0.01) 的体积非常小&…...
tp6 v3微信退款
/*** Notes:退款* param $out_trade_no 支付时候订单号(order表 original_bn)两个参数选一个这个要选对* param $out_refund_no 退款订单号* param $total 订单金额* param $refund 退款金额* Time: 2023-08-10*/public function refundMoney($out_trade…...

使用 AndroidX 增强 WebView 的能力
在App开发过程中,为了在多个平台上保持一致的用户体验和提高开发效率,许多应用程序选择使用 H5 技术。在 Android 平台上,通常使用 WebView 组件来承载 H5 内容以供展示。 一.WebView 存在的问题 自 Android Lollipop 起,WebVie…...

Maven基础之仓库、命令、插件机制
文章目录 Maven 仓库中央仓库和本地仓库中央仓库本地仓库 Maven 命令generate 命令compile 命令clean 命令test 命令package 命令install 命令 Maven 插件机制官方插件:Compile 插件Tomcat 7 插件 Maven 仓库 中央仓库和本地仓库 [✎] 简单一点说 中央仓库是一个网…...

【ArcGIS】经纬度数据转化成平面坐标数据
将点位置导入Gis中,如下(经纬度表征位置): 如何利用Gis将其转化为平面坐标呢? Step1 坐标变换 坐标变换,打开ArcToolbox,找到“数据管理工具”->“投影和变换”->“要素”->“投影”…...
使用自己的数据利用pytorch搭建全连接神经网络进行回归预测
使用自己的数据利用pytorch搭建全连接神经网络进行回归预测 1、导入库2、数据准备3、数据拆分4、数据标准化5、数据转换6、模型搭建7、模型训练8、模型预测9、完整代码 1、导入库 引入必要的库,包括PyTorch、Pandas等。 import numpy as np import pandas as pd f…...
103.216.154.X服务器出现漏洞了有什么办法?
服务器出现漏洞是一种严重的安全风险,需要及时采取措施来应对。以下是一些常见的应对措施: 及时更新补丁:确保服务器上的操作系统、应用程序和软件都是最新版本,并及时应用相关的安全补丁,以修复已知的漏洞。 强化访问…...

数据结构:堆的实现(C实现)
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》 文章目录 一、堆二、实现思路1. 结构的定义2. 堆的构建 (HeapInit)3. 堆的销毁 (HeapDestroy)4. 堆的插入 (HeapPush)5. 堆的删除 (HeapPop)6. 取堆顶的数据 (HeapTop)7. 堆的数据个数 (HeapSize…...

数据分析两件套ClickHouse+Metabase(一)
ClickHouse篇 安装ClickHouse ClickHouse有中文文档, 安装简单 -> 文档 官方提供了四种包的安装方式, deb/rpm/tgz/docker, 自行选择适合自己操作系统的安装方式 这里我们选deb的方式, 其他方式看文档 sudo apt-get install -y apt-transport-https ca-certificates dirm…...

urllib爬虫模块
urllib爬取数据 import urllib.request as request# 定义url url "https://www.baidu.com" #模拟浏览器发起请求获取响应对象 response request.urlopen(url)""" read方法返回的是字节形式的二进制数据 二进制--》字符串 解码 decode( 编码的格式…...

TCP消息传输可靠性保证
TCP链接与断开 -- 三次握手&四次挥手 三次握手 TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。 所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一…...
Visual Studio 与QT ui文件
对.ui文件鼠标右键,然后单击 Open with…在弹出的窗口中,选中左侧的 Qt Designer,然后单击右侧的 Add 按钮,随后会弹出一个窗口,在 Program: 输入框中输入 Qt Designer 的路径,最后单击 OK找到 Qt Designer…...

竞赛项目 深度学习验证码识别 - 机器视觉 python opencv
文章目录 0 前言1 项目简介2 验证码识别步骤2.1 灰度处理&二值化2.2 去除边框2.3 图像降噪2.4 字符切割2.5 识别 3 基于tensorflow的验证码识别3.1 数据集3.2 基于tf的神经网络训练代码 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 &#x…...

ORA-00845: MEMORY_TARGET not supported on this system
处理故障时,发现startup实例失败,报错ORA-00845: MEMORY_TARGET not supported on this system SYSorcl1> startup; ORA-00845: MEMORY_TARGET not supported on this system 查看alert日志,报错如下 Starting ORACLE instance (normal…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...