苹果开发初学者指南:Xcode 如何为运行的 App 添加环境变量(Environmental Variable)

概览

Xcode 15 在运行 SwiftUI 代码时突然报告如下警告:

Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.

不仅如此,Xcode 调试控制台中还提示我们需要添加特定的环境变量以进一步与该错误"亲密接触"。可是我们应该如何添加环境变量呢?

在本篇博文中,您将学到如下内容:

  • 概览
  • [1. 事件始末](#1. 事件始末)
  • [2. 按部就班:增加运行时环境变量](#2. 按部就班:增加运行时环境变量)
  • 总结

相信学完本课后,头发茂密的小伙伴们会对 Xcode 中添加环境变量这一常规技能了然于胸、信手拈来!那还等什么呢?

Let's go!!!😉


博文对应的视频在此,请恣意观赏吧!

苹果开发初学者指南:Xcode 如何添加环境变量

1. 事件始末

在 Xcode 15.2 调试运行 SwiftUI(模拟器 iOS 版本 17.2)编写的应用时,出现了如下错误信息:

可以看到该"错误"的描述相当模棱两可,既无法意会,也不方便言传:"该应用程序或库向 CoreGraphics 接口传入了一个非法的数字值(NaN 或根本不是数字)",这是个啥意思?

"肿"么会这样?难道源代码是外星人写的?

swift 复制代码
import SwiftUI

struct ContentView: View {
    @State var name = ""
        
    var body: some View {        
        VStack {
            TextField("", text: $name)
                .textFieldStyle(.roundedBorder)
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

如上我们可以看到,源代码简单的不要不要的,并没有什么特别的地方:我们只是用一个其貌不扬的 TextField 来捕获用户的输入而已。

另外我们还注意到该错误在 Xcode 预览中并不会出现,只会在真机或模拟器上运行时才会"面目狰狞"。

2. 按部就班:增加运行时环境变量

如果小伙伴们仔细观察就会发现,该错误只是其一,实际上 Apple 在该错误之后立马就给出了进一步探查它的方法:

If you want to see the backtrace, please set CG_NUMERICS_SHOW_BACKTRACE environmental variable.

"如果想看到回溯(backtrace)信息,请设置 CG_NUMERICS_SHOW_BACKTRACE 环境变量"(这里的回溯应该是出现该问题时的栈回溯)

那么如何设置这一环境变量呢?

首先,在 Xcode 中编辑项目的 Scheme 配置:

接着选择 Run 配置中的 Arguments 选项卡,我们即可轻车熟路的如愿添加指定的环境变量了:

注意,它只要我们添加一个名为 CG_NUMERICS_SHOW_BACKTRACE 的环境变量,至于它的值是啥并没有什么毛线关系,实际上只要这个变量存在就可以了,如上图演示的那样我们没有为它设置任何值。

再次运行原先的代码,我们发现了"新大陆":

swift 复制代码
Backtrace:
  <CGPathMoveToPoint+84>
   <+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:]+1120>
    <+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadius:segments:]+180>
     <+[UIBezierPath _roundedRectBezierPath:withRoundedCorners:cornerRadius:segments:legacyCorners:]+340>
      <-[_UITextChoiceAccelerationBubble backgroundImageView]+156>
       <-[_UITextChoiceAccelerationBubble anchorToTextIfNeeded]+500>
        <-[_UITextChoiceAccelerationBubble updateTextAnchorForParentView:]+156>
         <-[_UITextChoiceAccelerationBubble updateTextBoxHighlightForRect:inTextView:parentView:highlightColor:]+88>
          <-[_UITextChoiceAccelerationAssistant updateActivePromptForCandidate:displayRects:highlightOnly:]+352>
           <-[UIKeyboardImpl updateAutocorrectPrompt:correctionRects:]+492>
            <-[UIKeyboardImpl updateAutocorrectPrompt:executionContext:]+608>
             <__45-[UIKeyboardImpl touchAutocorrectPromptTimer]_block_invoke+112>
              <__56-[UIKeyboardScheduledTask handleDeferredTimerFiredEvent]_block_invoke+184>
               <-[UIKeyboardTaskEntry execute:]+200>
                <-[UIKeyboardTaskQueue continueExecutionOnMainThread]+304>
                 <-[UIKeyboardTaskQueue addTask:]+92>
                  <-[UIKeyboardScheduledTask handleDeferredTimerFiredEvent]+216>
                   <__invoking___+144>
                    <-[NSInvocation invoke]+276>
                     <-[_UIActionWhenIdle invoke]+52>
                      <__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+32>
                       <__CFRunLoopDoObservers+528>
                        <__CFRunLoopRun+968>
                         <CFRunLoopRunSpecific+572>
                          <GSEventRunModal+160>
                           <-[UIApplication _run]+868>
                            <UIApplicationMain+124>
                             <OUTLINED_FUNCTION_70+500>
                              <OUTLINED_FUNCTION_70+148>
                               <OUTLINED_FUNCTION_2+92>
                                <$s4test0A3AppV5$mainyyFZ+40>
                                 <main+12>
                                  102221544
                                   1022ca0e0                                    487a800000000000
Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API and this value is being ignored. Please fix this problem.
Backtrace:
  <CGPathAddLineToPoint+88>
   <+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:]+1140>
    <+[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadius:segments:]+180>
     <+[UIBezierPath _roundedRectBezierPath:withRoundedCorners:cornerRadius:segments:legacyCorners:]+340>
      <-[_UITextChoiceAccelerationBubble backgroundImageView]+156>
       <-[_UITextChoiceAccelerationBubble anchorToTextIfNeeded]+500>
        <-[_UITextChoiceAccelerationBubble updateTextAnchorForParentView:]+156>
         <-[_UITextChoiceAccelerationBubble updateTextBoxHighlightForRect:inTextView:parentView:highlightColor:]+88>
          <-[_UITextChoiceAccelerationAssistant updateActivePromptForCandidate:displayRects:highlightOnly:]+352>
           <-[UIKeyboardImpl updateAutocorrectPrompt:correctionRects:]+492>
            <-[UIKeyboardImpl updateAutocorrectPrompt:executionContext:]+608>
             <__45-[UIKeyboardImpl touchAutocorrectPromptTimer]_block_invoke+112>
              <__56-[UIKeyboardScheduledTask handleDeferredTimerFiredEvent]_block_invoke+184>
               <-[UIKeyboardTaskEntry execute:]+200>
                <-[UIKeyboardTaskQueue continueExecutionOnMainThread]+304>
                 <-[UIKeyboardTaskQueue addTask:]+92>
                  <-[UIKeyboardScheduledTask handleDeferredTimerFiredEvent]+216>
                   <__invoking___+144>
                    <-[NSInvocation invoke]+276>
                     <-[_UIActionWhenIdle invoke]+52>
                      <__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+32>
                       <__CFRunLoopDoObservers+528>
                        <__CFRunLoopRun+968>
                         <CFRunLoopRunSpecific+572>
                          <GSEventRunModal+160>
                           <-[UIApplication _run]+868>
                            <UIApplicationMain+124>
                             <OUTLINED_FUNCTION_70+500>
                              <OUTLINED_FUNCTION_70+148>
                               <OUTLINED_FUNCTION_2+92>
                                <$s4test0A3AppV5$mainyyFZ+40>
                                 <main+12>
                                  102221544
                                   1022ca0e0                                    487a800000000000

看来貌似是 CoreGraphics 在绘制圆角矩形时收到了某个"调皮捣蛋"的实参,我不知道这是否为 SwiftUI 中的一个 Bug,因为在示例代码中我们并没有任何明显"违规的行为"。


想要继续深入探索的小伙伴们可以在 Xcode 中设置如下符号断点:

objectivec 复制代码
[UIBezierPath _continuousRoundedRectBezierPath:withRoundedCorners:cornerRadii:segments:smoothPillShapes:]

然后运行 App,等进入中断后分析通用寄存器组,看一下到底哪个参数的值是"罪魁祸首":

这里限于篇幅就不进一步展开讨论了。


其实,我们高度怀疑这个错误不是用户输入而是用户在 TextField 上长按弹出系统选择菜单所引起的。这就意味着它作为一个系统层面上 Bug 的嫌疑又大了不少。

这个问题在未来系统中是否会自行消失呢,让我们拭目以待吧!


关于该"错误"的进一步讨论,请小伙伴们移步 Apple 开发者官方论坛一探究竟:


总结

在本篇博文中,我们介绍了 Xcode 15 运行 SwiftUI 代码出现"has passed an invalid numeric value to CoreGraphics"警告这一现象,并根据提示向小伙伴们演示了如何在 Xcode 中为 App 添加运行时的环境变量。

感谢观赏,再会!😎

相关推荐
东坡肘子12 小时前
肘子的 Swift 周报 #063|异种肾脏移植取得突破
swiftui·swift·apple
恋猫de小郭1 天前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
靴子学长2 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
一如初夏丿2 天前
xcode15 报错 does not contain ‘libarclite‘
ios·xcode
app开发工程师V帅2 天前
Xcode 文件缺失:Missing submodule xxx
ide·macos·xcode
app开发工程师V帅2 天前
Xcode 16 编译弹窗问题、编译通过无法,编译通过打包等问题汇总
macos·xcode
请叫我飞哥@6 天前
iOS在项目中设置 Dev、Staging 和 Prod 三个不同的环境
ios·xcode·swift
B.-6 天前
减少 Flutter 应用体积的常用方法
学习·flutter·android studio·xcode
hxx2218 天前
iOS swift开发系列--如何给swiftui内容视图添加背景图片显示
ios·swiftui·swift
名字不要太长 像我这样就好8 天前
【iOS】OC语法知识小结
ios·cocoa·xcode