Tag: 调试

带断点的Xcode调试(适用于初学者)

作为终身学习者,可以理解,犯错误是学习过程的一部分。 在编程中,这些讨厌的事情被称为🐞(错误)。 成为一名彻底而高效的调试器将使我成为一名更好的程序员,并最终使我能够长期编写出色的代码。 我认为最好对Xcode内的初学者级调试以及如何熟悉Breakpoint调试工具及其某些功能进行一些研究。 那么,什么是断点? 断点是一种调试工具,它使您可以暂停程序的执行直到某个时刻。 为什么要使用断点? 在代码中创建“暂停”点可以帮助您调查代码以查看错误发生的位置。 如何创建断点? 简单。 确定要在哪里暂停代码执行,然后单击左侧装订线以创建蓝色断点。 让我们看一下我们称为“调试区域”的出色之处。 上面的屏幕截图中发生了什么? 我创建了一个函数findSumOfEvens (),如果两个都是偶数,则它们将两个整数相加。 我在第24行调用了findSumOfEvens (n1:2,n2:4)函数后,在第25行设置了一个断点。该函数在第25行暂停,这意味着第二次调用findSumOfEvens (n1:1,n2: 6)未被称为YET。 我还注释了一些有用的Xcode调试按钮/区域 。 注意: 继续/暂停=(键盘快捷键是⌃ +⌘+ Y) 这些执行控制按钮: 跳过=(键盘快捷键是F6) 进入=(键盘快捷键是F7) 跳出=(键盘快捷键是F8) 我运行了该项目,控制台显示“您的偶数之和为6”。 接下来,我单击“ Step Over”按钮以执行下一行代码(第25行),这是我放置断点的位置。 在上方,您可以看到我“跳过”了实际上已执行IT的下一行代码,现在我的控制台已打印“您的两个数字都必须是偶数。 再试一次。” 我如何摆脱断点? 右键单击断点以删除: 等待,您的控制台中的(lldb)消息是关于什么的? LLDB代表“低级调试器”,它提供了用于iOS应用程序开发的基础调试环境。 它可用于查找和消除Swift和Objective-C代码中的问题。 断点和LLDB有何关系? 您可以在LLDB中键入快捷方式命令,以帮助您在代码的某些行设置断点,在代码中的许多点设置断点,列出所有断点并禁用断点。 在上面,您可以看到可以通过在LLDB中输入“选择器”(方法名称)来设置多个断点。 如果您有许多文件,并且不想单击所有文件来设置断点,这将特别有用。 在上方,您还可以“列出”项目中的所有断点。 在上方,您可以看到打印到控制台的详细列表信息,其中包括“命中计数” ,它表示我们达到某个断点的次数。 上面,我使用“ disable”禁用所有断点。 如果我只想禁用第二个断点 ,则应该输入“ breakpoint disable 2”。 上面,我在代码的特定位置设置了一个断点:第16行的ViewController.swift文件。 […]

iOS中的实用调试

当您的朋友为您做这些事时,您会想到“在哪儿学到的?” 这篇文章是为Meetup组OC Hack Nights的研讨会而创建的。 如果您在Irvine地区附近,并且想与好人一起做一些有趣的事情,请加入我们! 这是后面的Github链接:https://github.com/huyanhh/DebuggingDemo 调试。 好玩的东西。 这是没人想做的事,但却是必不可少的罪恶。 “ 如果调试是消除软件错误的过程,那么编程必须是将其引入的过程。 ” — Edsger Dijkstra 幸运的是,我们拥有使生活更轻松的工具。 让我们直接深入。 使用的工具和语言:Xcode 8,Swift 3 穴居人调试 有趣的名字,但是它的名字很准确。 命名是在Objective-C时代的某个地方发明的。 这种调试类型是快速,易于使用的调试类型。 除了输入代码外,无需进行任何设置。 我们可以选择打印报表: print 经典的打印功能,您可以打印出大多数带有完整描述的对象,而无需以任何特定方式对其进行格式化: print(self.view)//产生 <UIView:0x7f896850a810; 框架=(83 96; 203 138); 自动调整大小= RM + BM; 层= > NSLog 作为Objective-C函数,在Swift中也可以使用。 主要区别在于您将使用格式说明符来指定要在运行时传递的参数类型。 它类似于Java中的System.out.format() 。 在正常情况下,您可能希望使用print ,但是假设我需要观察语句上打印了哪个线程,然后可以在两个不同的函数上使用NSLog进行检查。 容易吧? NSLog(“某些视图:%@”,self.view) //收益 //格式:日期时间process_name [process_id:thread_id] 2017-03-28 10:46:11.222 DebuggingDemoFinished […]

ARC Swift中内存管理的第一种方法-第1部分

ARC代表自动引用计数,它是Objective-C和Swift的Clang编译器的功能,可以为我们管理内存。 每次创建类实例时,ARC都会分配一块内存,该空间将存储与该实例相关的所有信息。 一旦您的代码不使用它,ARC就会取消分配该类实例,因为应用程序不再需要它。 ARC仅适用于引用类型 ,不适用于值类型,如Swift中的“ 结构”或“ 枚举” 。 因为我想向您展示如何使用对象图管理内存,所以我在Xcode中创建了一个简单的视图项目,而不是Playground文件。 下面的示例显示ARC如何处理内存: 如上所示,为类实例分配的内存仍然存在。 即使将nil分配给’reference1’和’reference2’,分配的内存也不会释放。 这是因为还有另一个引用指向以前创建的实例,因此ARC在需要之前不会释放此内存。 您可以在下面的示例中看到: 尽管ARC通常可以成功地为应用程序管理内存,但是在某些情况下,我们需要提供额外的信息。 定义代码各部分之间的关​​系将有助于我们避免诸如强引用保留周期或内存泄漏之类的问题。 在前面的示例中,跟踪ARC如何为我们管理内存确实很容易,但是当我们开始编写复杂的代码时,这将变得更加困难。 因此,在向ARC提供信息时我们需要小心。 在编程时,我们最常犯的错误是有两个指向彼此的不同引用。 由于它们都是在内存中分配并使用的,因此ARC将永远不会释放内存,因为这种环境会导致强大的参考周期。 即使将“ nil”分配给这些实例,仍将分配内存。 在下一个示例中,我们将创建一个保留周期,并观察如何处理内存。 可以看到,没有调用’deinit’函数,这是因为类实例仍然存在。 提示:只需查看内存检查器中的紫色警告图标,即可轻松检测保留周期和内存泄漏 为了解决此问题,我们可以为参考提供额外的信息,以便ARC在管理内存时将其考虑在内。 在这种情况下,我们将把“ B”类到“ A”类的“ a”引用设置为“弱”以避免这种问题。 ARC是一项强大的功能,可帮助我们避免iOS上的内存处理。 但是,在某些情况下,我们需要特别注意。 将两个引用相互指向会导致强烈的引用周期,这不是预期的行为,因此我们需要通过提供一些额外的信息来避免此问题。 下一部分见,我们将通过一些示例了解这些关系之间的差异以及如何正确使用“ 弱 ”和“ 无主 ”。

如何寻求帮助(编码)

由于多年来我一直将自己视为新手开发人员,因此现在已经很熟悉了。 我有一点时间,我只是打开笔记本电脑,在个人学习项目上进行一些工作,也许要完成一个教程,然后:pwhoomp! 包版广告。 在一个小时内,发现两个错误使我无法通过初学者级iPhone应用程序编程教程的初始阶段,有人向我指出,编写其他过程可能对其他人有用。 开始。 首先,我分享一些背景知识,以防您可能希望学习类似的技能,或者在开发学习过程中觉得自己一个人,也许我们有一些共同点。 我是50岁的兼职产品经理,他了解vi和HTML,一些CSS,一些JavaScript。 从牛顿时代开始,我就一直崇拜苹果移动产品。 掌上功能强大的计算机? 对于在Littles上长大的人,您betcha! 这些天,我正在学习Swift,以开发自己的教育应用程序。 (我也教。)我的自学课程结合了Apple的App开发和Swift iBook以及Paul Hudson的Hacking with Swift教程。 昨晚,我正在学习第五个教程,很高兴学习如何构建文字游戏,这是一个具有明显现实世界教育价值的项目。 只是完成设置,在Apple的Xcode IDE中创建新项目,然后从默认视图切换到UITableView感觉就像是一项成就。 下一步是在ViewController.swift中添加一些行以读取文件,并将视图标题(在手机屏幕上看到的内容)设置为以下单词之一。 表面上看,这比听起来容易得多,因为提供了所有代码。 如果您愿意,可以只复制粘贴。 因为学习起来感觉更好,所以我会尝试通读,理解,重新键入和搜索Google。 当然,语法错误会逐渐蔓延,但是Xcode会警告我这些错误。 完成输入要读取文件的功能后,并设置了初始表格视图,该教程指示:“现在按Cmd + R键运行该应用程序,您应该在顶部看到一个八个字母的单词,准备就绪太好了,我喜欢构建和运行部分,我计算机屏幕上的假装电话,一点点的工作软件。 除了… 没啥事儿。 更具体地说(因为这实际上是我在其他人的问题报告中想要理解的东西),模拟器确实显示了所请求的假装设备(我将我的设备设置为iPhone 5s,因为它非常适合我的MacBook Air屏幕),但是我既没有看到表格视图,也没有看到标题。 最初我不知道为什么。 说实话,在这里。 每当我遇到这些时刻之一时,我都会感到恐慌。 我有一个相当消极的内部独白,像这样。 “来吧,您永远不会成为一名开发人员。 您应该做其他事情。 我一直压扁这个,但我听到了。 我认为很多学习者都这样做。 我知道我需要寻求帮助。 不要害怕问,但请仔细考虑您的要求。 当我们处于编码障碍时,这意味着我们的软件无法按预期运行。 暂停。 深呼吸。 您可以对此进行推理。 您期望发生什么? 发生了什么事呢? 在这种情况下,本教程包括一个屏幕截图,因此我确切地知道应该看到的内容:带有标题的UITableView。 表格视图和标题均丢失。 除了空白的模拟器屏幕外,Xcode还在ViewController.swift中标记了这一行: 标题= allWords [0] 我还在调试控制台中看到“严重错误:索引超出范围”。 […]

👀调试您的Quick Look插件

当您想将Quick Look插件捆绑在您的应用程序中,并且对该应用程序有一些依赖性时。 调试此Quick Look插件可能很麻烦。 怎么样? 现在最简单的测试方法是什么? 这有点愚蠢,但这始终对我有效100%。 构建您的应用程序目标(捆绑了Quick Look插件)。 在Xcode项目文件夹结构中,应该打开“ 产品”组,然后右键单击.app文件,以便在Finder中显示它。 现在,将.app文件复制到/Applications文件夹。 该应用程序已经存在时,只需将其覆盖即可。 打开新复制的应用程序。 现在,强制重新加载“快速查看生成器”列表。 qlmanage -r运行qlmanage -r 。 选择要使用插件预览的文件,然后点按空格键。 别客气! 🙌 更多技巧 当您想要显示一些日志记录时,您可以做的最好的事情就是在代码中使用NSLog 。 专业提示 :使用表情符号可以更好地查看日志。 运行qlmanage -m | grep gpx qlmanage -m | grep gpx命令可以查看链接到gpx扩展名的所有Quick Look插件。 这样,您可以确定使用的插件正确。 可能使用了错误的Quick Look插件,最简单的方法是删除错误的插件,然后再次运行qlmanage -r 。 可能并非总是有效的另一件事是重新加载缩略图缓存 。 在运行qlmanage -r cache命令之后,您将需要重新启动Finder以重置图标。

使用XCode进行调试

手机上的内存是共享资源。 管理不当的应用程序会耗尽内存,崩溃并遭受性能急剧下降的困扰。 当我们将内存的给定部分分配给一组对象,而在使用完它们后忘记释放它,则会发生内存泄漏。 这意味着系统永远无法回收内存并将其用于其他用途,这最终意味着我们将耗尽可用内存。 尝试查找内存泄漏时,一个好的第一步是运行该应用程序,并查看Xcode中的内存使用情况图。 如果在使用应用程序时内存使用量趋于增加,则可能是某些内存没有适当释放。 内存图 Xcode内存图调试器有助于查找和修复保留周期和泄漏的内存。 激活后,它将暂停应用程序执行,并显示当前堆中的对象以及它们之间的关系以及哪些引用使它们保持活动状态。 可以通过选择“内存图”来启动“内存图”调试器 调试菜单栏中的调试器按钮。 在下面的文章中了解有关内存图调试的信息。 iOS-使用Xcode内存图调试器识别内存泄漏 来自petethedeveloper.com medium.com的交叉发布 在Xcode 9中使用内存图调试器 我从未真正花费时间来正确学习如何使用乐器。 当然,我知道如何使用Time Profiler和… medium.com 可能会有所帮助 主线程检查器 选择您的应用方案->产品>方案>编辑方案 方案1:如果主线程检查器为“未检查 ”。 在多线程环境中使用Logger。 线程清理程序告诉我们,由于多个线程正在访问我们的日志并间接访问logEventSource,因此存在竞争状态。 这将导致我们发生意外的行为,这可能很难跟踪或复制。 现在我们如何避免这种情况? 同步功能代码。 互斥锁 信号 GCD 让我们使用苹果推荐的方法: 生成的崩溃报告通常显示每个堆栈跟踪帧的内存地址,而不是源代码位置。 这使得很难确定错误在代码中发生的位置。这些调试符号包含所需的信息,以从内存地址转换为关联的源文件和行号。 象征性 符号化是将返回地址转换回人类可读的方法/文件名和行号的过程。 符号化使您更容易识别错误的根源并及时解决错误。 编译源代码时,编译器会将人类可读的源代码转换为机器可读的代码,并创建一个已编译的二进制文件。 它还会生成调试符号和映射表。 如果您看到映射表,则每个调试符号都将映射到已编译二进制文件中的确切机器指令,并映射到生成它的源代码中的行号。 有两种类型的构建,一种是调试构建,另一种是发行版本。 因此,根据构建设置,默认情况下,调试构建将调试符号存储在二进制文件中,另一方面,发布构建将调试符号存储在dSYM文件中以减小二进制文件的大小。 在构建过程中,XCode将从主可执行文件( 二进制 )中剥离所有调试信息,并将其放入名为dSYM的特殊文件中。 这有助于使我们的可执行文件更小,更易于分发给用户。 可能会有所帮助 谢谢!!!

Xcode调试技巧和窍门— WWDC 2018

调试是整个软件开发过程不可或缺的一部分。 一个好的程序员应该具有高效的调试技能,以便从长远来看编写无错误的代码。 通过本文,我们将熟悉通过LLDB命令进行的Xcode调试,从而避免了每次修改都需要重新编译代码的麻烦。 提示1: 表达命令 有效地利用expression命令并以根本不需要重新编译代码的方式配置断点。 如果要在命中断点时撤消任何代码,请在Xcode控制台中使用expression命令。 在Xcode控制台中,在下面的命令中输入要执行的代码。 表达式“要评估的代码行” 断点也可以配置为通过在编辑断点选项卡内添加相同的表达式命令来自动完成。 使用expression命令在调试之间插入代码。 在下面的示例中,文本的原始值是“商业新闻版块”。 在控制台中使用expression命令可以修改文本字符串。 什么时候使用? 如果需要查看更复杂的数据或更改程序数据,则可以使用常规的“表达式”命令。 它在调试时接受一个表达式,并在当前选定帧的范围内对其求值。 提示2:符号断点 符号断点非常强大,可以将其添加到名称与断点符号匹配的任何方法中。 开发人员无需担心方法的签名或方法所属的模块。 如下例所示,在断点的符号字段中添加要为其触发断点的方法名称。 当[UILable setText:]之类的目标C格式方法在符号断点中添加其名称时被触发。 在下面的示例中,该行触发了断点。 cell.title.text = getTextForEachSection 在这种情况下,当遇到断点时,我们将开始查看汇编代码,因为我们没有UIKitCore的源代码。 如果您使用的是系统框架的汇编代码,则不必担心,因为我们可以使用伪寄存器检查传递给setText函数的参数。 伪-调试器提供的寄存器可以查看寄存器保存的参数。 $ arg1 —我们可以看到目标c消息的接收者 (SEL)$ arg2 —选择器。 (SEL)是必需的,因为LLDB不知道这些参数的类型。 $ arg3 :第一个参数传递给函数 什么时候使用? 修复控制台中的自动布局警告(如UIViewAlertForUnsatisfiableConstraints)和布局相关的警告(如UICollectionViewFlowLayoutBreakForInvalidSizes)。 提示3:向断点添加条件 当更多的对象具有与断点匹配的符号时,可能会出现频繁击中符号断点的情况。 我们可以通过添加一个仅在满足断点条件时才触发断点的条件来避免这种情况。 秘诀4:一杆断点 一个临时断点,仅在其触发之前存在,然后将其自动删除。 在击中一个击球断点后,可以使用它激活任何其他断点。 断点集-一键式true –name“-[UILabel setText:]” 在上面的示例中,仅在击中一个镜头断点后才激活符号断点“ setText”。 提示5:跳过代码行的执行以简化调试。 在许多情况下,我们希望通过跳过一些代码来节省调试时间。 我们可以通过要求调试器跳过代码来做到这一点。 […]

执行动作,不要停止执行

正确使用调试工具可以帮助开发人员节省大量时间。 例如,考虑最基本的断点:它使我们能够暂停程序的执行,以便逐步对其进行分析。 现在,只需考虑通过手动在每行上添加输出到控制台来执行该过程所花费的时间。 事情很快就会变得一发不可收拾,难以管理。 事实证明,我们大多数人习惯的标准断点只是冰山一角,而且Xcode拥有一整套方便的工具,旨在加快调试工作流程。 让我们从我们大多数人已经经历过几次的事情开始:我们设置一个断点,当它被触发时,我们键入一个命令,例如po myVariable ,然后继续执行。 当然,如果我们需要执行多次以上,此手动操作将变得非常繁琐。 幸运的是,将其自动化非常简单: 右键单击断点>“编辑断点…” 点击“添加动作” 选择“调试器命令” 输入您的命令 选中“评估操作后自动继续” 从现在开始,无论何时触发此断点,都将执行自定义调试器命令,并且此后将立即恢复执行,从而无需进行任何手动操作。 节省了很多时间👍 有时我们希望仅在满足特定条件时才触发断点。 再一次使用“ Edit Breakpoint…”,设置这样的条件非常容易: 在此示例中,条件非常简单,但是可以使用布尔运算符( && , || , ! ,…)执行函数调用,因此可以更轻松地处理更复杂的表达式。 相反,有些时候我们希望断点仅从第二次触发就停止执行。 例如,考虑一下在创建对象时第一次调用该函数,然后在事件发生时再次调用的函数。 如果我们只想调试第二种调用,最好过滤掉第一种。 再次使用“编辑断点…”选项已经在等待我们: 当引发异常或错误并没有捕获到异常或错误时,应用程序崩溃,并且调用堆栈被打印到控制台。 此输出通常对于识别错误的来源非常有帮助,但实际上并不允许检查引发错误的情况。 那是一种新的断点开始起作用的时候。 到现在为止,我们使用的所有断点都以某种方式固定在我们的代码上,这意味着它们已在应用程序的特定行上显式设置。 为了设置在发生错误时触发的断点,我们需要查看符号断点的侧面,这意味着不与特定行链接的断点,而是与定义良好的事件相关的断点,在本例中为发生错误。 为此,Xcode已经提供了两种此类断点,具体取决于您是否对Swift或Objective-C错误感兴趣: 很棒的事情是,您还可以编辑它们,以便通过过滤特定的Swift.Error类型或在引发错误或Swift.Error错误时触发来使它们更加适合您的需求。 异常和错误断点是一种特殊的符号断点,但是也可以定义更多的通用断点。 例如,可以创建一个断点,该断点将在控制器上调用viewDidLoad()时触发: 当您知道正在调用某个方法(例如,一个模态控制器被关闭)并且您试图查明此调用的源时,这可能是一个非常有用的工具。 我们所有人都面临着AutoLayout问题。 通常,我们通过控制台错误消息了解这些运行时问题,这些错误消息指出自动布局引擎“无法同时满足约束条件”。 但是,在复杂的应用程序中,要弄清楚哪个视图恰好触发了错误,可能会很复杂。 查明根本原因的一种好方法是在项目中添加“约束错误断点”。 然后,每当发生新的自动布局问题时,断点将自动触发👌 Xcode 11中的新增功能,引入了一种新型的符号断点。 它称为“运行时问题断点”,实际上实现了以前必须在编译方案中启用的检查。 其中,您会找到一个“主线程检查器”,该“主线程检查器”将在从后台线程访问UIKit或AppKit对象时被触发,或者会找到一个“线程清理程序”来帮助您检测竞争状况。 当您考虑它时,断点就是专注于应用程序代码的构造。 但是,应用程序是由代码和数据组成的,因此具有等同于断点的功能当然很有用,以便观察数据在应用程序运行时如何变化。 碰巧的是,这样的构造在Xcode中已经可用,尽管它不像断点那样可见,它被称为watchpoint 。 […]

Xcode 9.0 Beta(iOS 11上的无线调试)

调试。 通过网络无线调试iOS和tvOS设备,Metal的新调试器以及整个Xcode的更多功能。 源代码管理。 所有新的源代码控制导航器和对GitHub帐户的集成支持,可快速浏览存储库并将您的存储库推送到云中。 内置Xcode Server。 连续集成机器人可以在任何使用Xcode 9的Mac上运行,而无需安装macOS Server。 新的Playground模板。 包括旨在在iPad的Xcode和Swift Playgrounds中良好运行的iOS模板。 新的构建系统。 Xcode新构建系统的可选预览提供了改进的可靠性和性能。 无线调试 网络调试需要在MacOS 10.12.4或更高版本上运行的Xcode 9.0或更高版本,并且在设备上需要iOS 11.0或更高版本或tvOS 11.0或更高版本。 设置iPhone,iPad或iPod touch 选择“窗口”>“设备和模拟器”,然后在出现的窗口中,单击“设备”。 使用避雷线将设备连接到Mac。 在左列中,选择设备,然后在详细信息区域中,选择“通过网络连接”。 Xcode与您的设备配对。 如果Xcode可以使用网络与设备连接,则在左列中设备旁边会出现一个网络图标。

使用启动参数在Xcode中进行核心数据调试

Core Data是Apple的对象图管理和持久性框架,适用于iOS,macOS,watchOS和tvOS。 它已经存在很长时间了,因此是在应用程序中持久存储结构化数据的绝佳解决方案。 尽管Xcode中一些鲜为人知的功能可以为您提供很多帮助,但是Core Data Debugging可能会有些困难。 “让您快速入门的一种好方法是观看有关核心数据的WWDC会议。” 为了更好地了解您的应用程序正在保存的内容,直接打开SQL数据库非常有用。 检索数据库位置的最简单方法是启用SQL调试输出: -com.apple.CoreData.SQLDebug 1 您可以在Xcode的方案编辑器中设置此参数以启用SQL Core Data Debugging: 级别可以设置为4,以实现更详细的输出级别。 它将使您深入了解已执行的提取请求,访问的属性或保存的数据,并且通常是核心数据调试的绝佳工具。 启动应用程序时,它还会向您显示sqlite数据库文件的位置: CoreData:注释:在以下位置连接到sqlite数据库文件:/ Users / antoinevanderlee / Library / Developer / CoreSimulator / Devices / AB66C5B9-D1C1-45C4-9324-DB0E91FAB4F9 / data / Containers / Shared / AppGroup / C6934424-5E58-4164-8593- 3CC0D60D2BB5 / Coyote.sqlite“ 可以使用相同的SQL调试启动参数来发现繁琐的查询或在应用中触发很多请求的位置。 WWDC 2018的核心数据最佳实践会议更详细地介绍了此技术。 核心数据旨在在多线程环境中工作。 但是,并非Core Data框架下的每个对象都是线程安全的。 要在多线程环境中使用Core Data,请确保: 受管对象上下文绑定到初始化时与之关联的线程(队列) 从上下文中检索到的受管对象被绑定到上下文所绑定到的同一队列 […]