苹果开发初学者指南: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 添加运行时的环境变量。

感谢观赏,再会!😎

相关推荐
青花瓷10 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
Rverdoser2 天前
xcode更新完最新版本无法运行调试
xcode
今天也想MK代码2 天前
在Swift开发中简化应用程序发布与权限管理的解决方案——SparkleEasy
前端·javascript·chrome·macos·electron·swiftui
#摩斯先生3 天前
IOS 防截屏实现
ios·xcode
胖虎14 天前
CocoaPods安装步骤详解 - 2024
ios·cocoa·xcode·cocoapods
阿里嘎多8716 天前
GO中的文件操作
开发语言·golang·xcode
low神7 天前
Mac打开环境变量配置文件,source ~/.zshrc无法打开问题解决
android·macos·nvm·环境变量·android_home·zshrc
lmyuanhang7 天前
ios Framework版本号的问题。
ide·macos·xcode
東三城7 天前
【ios】---SwiftUI开发从入门到放弃
ios·swiftui·swift·1024程序员节
MrZWCui8 天前
iOS18 取消/适配TabbarController缩放动画
学习·ios·objective-c·xcode·ios18