如何解决/处理委托 EXC_BAD_ACCESS 错误?对象C

2024-03-23

我正在编写一个库(iPhone 的 Obj-C),我想打包并出售它,所以我显然需要在将其出售之前解决所有设计问题。我还利用这个库来帮助我开发另一个应用程序。

我的库很大程度上建立在任务委派的基础上。我的主要功能是启动一个(可能)长时间运行的进程,完成后,我在类的委托中调用委托协议方法。

这里的另一个复杂因素是,我经常安排此任务每 30 秒左右触发一次。通常,我使用 [self PerformSelector:@selector(someMethod:) withObject:nil afterDelay:30] 而不是使用 NSTimer 来执行此操作。然后,当委托方法成功返回时,我处理返回的数据并在另外 30 秒后触发该方法。这让我在方法调用之间有 30 秒的时间,而不是从一个调用开始到下一个调用之间的时间为 30 秒。 (这主要是为了防止调用时间超过 30 秒,这种情况不应该发生。)

我捕获的错误是,有时委托回调方法会因 EXC_BAD_ACCESS 错误而失败。根据我的调查,自从长时间运行的进程启动以来,我的类库的委托似乎已经消失(已释放/解除分配)。因此,当它调用 [[self Delegate] doSomeDelegateMethod] 时,它正在访问一个已释放的对象。

我尝试首先检查 [[self Delegate] respondsToSelector:@selector(doSomeDelegateMethod)],但即使该访问显然也会引发 EXC_BAD_ACCESS。

检查 [self Delegate] == nil 似乎也不是正确的方法。

在这个特定的实例中,我认为我已经解决问题的一种方法是,当实例化我的对象的视图控制器消失时(因此在前往垃圾转储的路上),我调用 [NSObject cancelPreviousPerformRequestsWithTarget:self]。这显然解决了问题。 (这个“修复”是否也表明我的对象“知道”即将到来的呼叫并将其自身保留在内存中,直到它能够成功地、绝望地发射最后一枪?)

这看起来像是在枪伤上贴了创可贴。是的,这一次似乎阻止了我的应用程序崩溃,但我的直觉告诉我,这是一个糟糕的解决方案。

我还考虑过在 viewWillDisappear:animated: 方法中将自定义对象设置为 nil,这可能是正确的编码模式,但客户必须如此精确地处理我的对象似乎并不正确。

然而,真正困扰我的是,作为一个库开发人员,我还没有找到一种方法来“装箱”我的代码,这样如果用户不执行以下操作,它就不会抛出异常正确的事情。基本上,我想要一种方法来获得我的对象:

  1. 获取请求。
  2. 去寻找答案吧。
  3. 找到答案。
  4. 尝试返回答案。
  5. 意识到另一端没有任何东西。
  6. 放弃并自行死亡。 (好吧,所以“自己死”可能不会发生,但你明白了。)

一个有趣的侧面:

我防止此类错误发生的主要原因是:

我执行了以下步骤:

  1. 构建了我的库的 .h/.m 文件。
  2. 生成我的库的 .a 输出文件。
  3. 将我的库的 .a/.h 文件导入到另一个项目中。
  4. 出现上述错误。
  5. 必须仔细阅读应该隐藏在 .a 文件中的 .m 文件之一的代码。

我在这里错过了什么吗?如果我的整个源代码向客户端抛出错误,我真的会冒暴露整个源代码的风险吗? (这只是一个次要问题,但我在这里相当担心!)

感谢您提供的任何帮助,帮助我成为一名更好的程序员!

- -编辑 - -

我发现了另一个重要的原因。在另一个视图控制器中,我使用这个库,我实现了 NSTimer 策略。如果视图从导航堆栈中弹出(即在 viewWillDisappear:animated: 方法中),我将使所述计时器无效。因此,视图消失后,不会再有任何调用进入我的库。

问题是:如果视图消失怎么办?在中间长时间运行的调用?是的,这很棘手而且不太可能做到,但我只是在模拟器上发生了这种情况。尤其,THIS这就是为什么我正在寻找一种解决方法,让我的代码意识到“嘿,这个管道的另一端没有任何东西”,然后优雅地失败。任何人?

Thanks!


解决这个问题有几种方法:

  • 传统的委托方法(UITableViewDelegate) 要求在离开之前明确自己的代表身份。传统上这是在dealloc代表的otherObject.delegate = nil。如果不这样做,就会出现编程错误。这基本上就是你所看到的。当委托者和委托者的生命周期基本相同时,这是常见的模式。

  • 另一种方法是如何NSURLConnection处理它:保留你的代表直到你完成为止。其运作良好的关键在于NSURLConnection有自己的生命周期,因此保留循环会自动解决。UITableView无法保留其委托,因为这几乎总是会创建永久保留循环。如果你的对象存在一段时间然后消失,那么这是有道理的。通常,委托的生命周期比委托者短得多,因此保留循环不会造成任何损害。

任何调用的对象performSelector:withObject:afterDelay:应该总是打电话cancelPreviousPerformRequestsWithTarget:self在它自己的dealloc。但这与您的代表无关。它应该是独立于对象本身的。(我不知道为什么我一直认为这是真的,然后再次向自己证明它不是。当你调用 PerformSelector:...afterDelay 时:,你被保留了,所以你不能在它触发之前取消分配。我的旁注虽然是正确的,但在这里并不相关。)

边注 cancelPrevious...根据我的经验,真的很贵。如果你必须打电话cancelPrvious...很多时候,我建议保留你自己的一次性NSTimer并在它触发时重置它以获得相同的效果。performSelector:withObject:afterDelay:只是一次性计时器的包装。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何解决/处理委托 EXC_BAD_ACCESS 错误?对象C 的相关文章

  • Facebook iOS 选择好友表空白

    我正在尝试将 选择的朋友 添加到我的 iOS 应用程序中 我设置了登录视图 登录后 我打开朋友选择器 但它显示为空白 我看到带有 完成 和 取消 按钮的表 但表中没有加载任何朋友 IBAction selectFriendsButtonAc
  • ios Facebook 添加 FBNativeAdView 作为子视图

    我想使用预建视图FBNativeAdView 不想自定义 FBNative 广告 如link https developers facebook com docs reference ios current class FBNativeAd
  • 启动使用 Simperium 的应用程序时 objectFromJSONString 崩溃

    我得到了一个JSON当我尝试启动使用 Simperium 框架的应用程序时崩溃 NSCFString objectFromJSONString unrecognized selector sent to instance 0x6c561a0
  • iPhone 开发 - sqlite3_bind_int 不起作用

    我正在尝试使用以下代码在数据库中插入一些数据 void insertLocationOnDatabase LocationType aLocation sqlite3 stmt stmt int location aLocation loc
  • 如何读取 Xcode 6.1 Instruments .trace 文件?

    我一直在尝试阅读 trace文件 我使用生成的custom仪器模板 仪器 自动机 分配 Leaks using 仪器 https developer apple com library mac documentation Developer
  • 将 Xcode 4.5 新 XIB 文件恢复到 iOS<6

    我已经安装了Xcode 4 5 with iOS6 SDK以及其他用于测试目的的旧 SDK 从 4 3 到 6 0 很美 但是有一个BIG问题 生成一个新的 XIB 文件以兼容 iOS6 这是一个问题 因为我的应用程序需要运行在旧设备 不只
  • 如何使用存储在 Cocoa Touch 框架中的 Localized.strings?

    我想为 CocoaTouch 框架添加多语言支持 问题 可本地化的字符串我创建的文件仅被使用NSLocalizedString当它是主应用程序及其目标的一部分时 我想将其存储在框架内以将事物分开 我怎样才能使用可本地化的字符串当放置在 Co
  • 在 SwiftUI 中,如何执行手势但将手势转发到其后面的视图?

    我正在创建一个工具提示系统 如果用户触摸工具提示之外的任何地方 我想关闭工具提示 我希望这样在工具提示之外的触摸既可以消除工具提示 又可以激活用户点击的任何控件 因此 您可以打开一个工具提示 然后仍然单击工具提示外部的按钮 并在第一次点击时
  • 在 UIView 中绘制彩色文本 -drawRect: 方法

    我正在尝试在我的中绘制彩色文本UIView子类 现在我正在使用单视图应用程序模板 用于测试 除了以下内容外 没有任何修改drawRect method 文本已绘制 但无论我将颜色设置为什么 它始终是黑色的 void drawRect CGR
  • Cordova Phonegap“导出失败”错误代码 70 构建 ios 时

    我目前正在使用 Cordova Phonegap 构建 iOS 应用程序 本来工作正常 但现在运行时出现错误cordova build ios在终端中 我收到以下错误 导出失败 错误 命令的错误代码 70 带有参数的 xcodebuild
  • 将 UIRefreshControl 用于 UIWebView

    我在 iOS 6 中看到了 UIRefreshControl 我的问题是是否可以通过下拉来刷新 WebView 而不是像在邮件中那样让它弹出 我使用 rabih 的代码是 WebView UIRefreshControl refreshCo
  • 基于 JavaScript 的 iPhone UI 框架

    我们有一个基于推送的网络应用程序 最近 我们计划为其制作一个 iPhone 应用程序 就像 Facebook 拥有 iPhone 应用程序和网站一样 我们正在寻找一个可以让我们快速前进的 UI 框架 我翻阅过PhoneGap http ww
  • Swift 3 中数组的 indexOf(_:) 方法的替换

    在我的项目 用 Swift 3 编写 中 我想使用从数组中检索元素的索引indexOf 方法 存在于 Swift 2 2 中 但我找不到任何替代方法 Swift 3 中是否有任何好的替代方法或类似的方法 Update 我忘记提及我想在自定义
  • ExpandableLabel iOS 中的“少看”

    我正在使用第三方库可扩展标签 https github com apploft ExpandableLabel实施一个see more特征 我正在寻找仅快速的解决方案 其中包含标签中的文本而不是按钮中的文本 因此这可以完美地工作 添加库并更
  • SwiftUI - 从 NSObject 继承的 ObservableObject 在 iOS 13 中不会更新

    我知道 这是 无法在 iOS XX 中工作 问题之一 但我完全陷入困境 所以我有一个ObservableObject继承自的类NSObject 因为我需要听委托方法UISearchResultsUpdating class SearchBa
  • 禁用 iPhone 4S / 新 iPad 键盘上的听写按钮

    我们的应用程序是一个医疗保健应用程序 我们的应用程序中有一个符合 HIPAA 标准的语音识别器 所有听写都可以通过它进行 医院不希望医生意外开始与不符合 HIPAA 标准的 Nuance Dragon 服务器进行对话 因此 我正在寻找可以抑
  • iOS 键盘显示后分屏宽度

    我刚刚开始研究 Cordova 应用程序对分屏多任务处理的支持 到目前为止 该应用程序在模拟器中的 iPad 上显示和调整大小都很好 但是当我单击编辑字段并显示软件键盘时 100 宽度的值开始返回整个屏幕 而不是给出的窗口 初始显示 到目前
  • 如何设置仅适用于 iPhone 或 iPad 的视口?

    我有一个网站 需要在 iphone 上使用 0 3 的视口值 但在 ipad 上使用 0 7 有没有办法只为 iPhone 或 iPad 设置视口 这是一种解决方案
  • 在iOS中设置框架的原点

    我正在尝试以编程方式设置框架的原点 Method1 button frame origin y 100 方法二 CGRect frame button frame frame origin y 100 我尝试了方法 1 但它不起作用 显示错
  • 我如何用 javascript/jquery 进行两指拖动?

    我正在尝试创建当有两个手指放在 div 上时拖动 div 的功能 我已将 div 绑定到 touchstart 和 touchmove 事件 我只是不确定如何编写这些函数 就像是if event originalEvent targetTo

随机推荐

  • 在经典ASP页面调用存储过程

    我一整天都在努力从经典 ASP 页面调用存储过程 我有一些基本的菜鸟问题 首先 这是向我的命令添加参数的最佳方法吗 cmd Parameters Append cmd CreateParameter SubmissionDate adDBT
  • 如何使用 cmp 将排序从 python 2 转换为 python 3?

    我正在尝试将用 python 2 编写的代码转换为 python 3 nums 30 31 num sort cmp lambda x y cmp y x x y 不知道如何在 python 3 中做到这一点 因为 cmp 被删除了 我相信
  • 测试 Dart 值是否实际上是一个函数?

    是否可以测试一个值是否是一个可以调用的函数 我可以轻松测试 null 但之后我不知道如何确保传入的参数实际上是一个函数 void myMethod funcParam if funcParam null How to test if fun
  • 检查 VSTS 中以前的构建信息(VSTS API)

    在执行 VSTS 构建期间是否可以访问以前的构建变量 例如 我可以获得先前构建的 Build SourceVersion 或 Build QueuedBy 吗 我可以通过 Build SourceVersion 等构建变量获取当前构建信息
  • 使用 LDAP 用户名作为实体名称

    我正在使用 Hashicorp Vault 1 9 0 并且启用了 LDAP 身份验证方法 该方法按预期正常工作 但有一个问题 LDAP 是我们独特的身份验证方法 当然 除了令牌之外 并且 LDAP 用户不是提前在 Vault 中创建的 因
  • 在 PHP 中搜索并获得双重结果

    这是我的 PHP 代码 我用它从 PHPMyAdmin 的数据库 Mysql 中进行搜索 但是当我得到结果时 它显示双倍 我不明白为什么是双的 如果它是 for foreach 循环 那么我将使用什么来代替它 请帮我解决代码
  • Python (CherryPy) Web 应用程序部署在本地,但在 Intranet 上不可见

    我使用 CherryPy 创建了一个 Python Web 应用程序 并部署在我的本地计算机上 当我尝试从家里的另一台计算机上查看它时 没有任何结果 但是 如果我创建一个简单的 html 文件 并使用以下命令部署它 python m Sim
  • 如何将 SAP .txt 提取转换为 .csv 文件

    我有一个 txt 文件 如下面报告的示例所示 我想将其转换为 csv 表 但我没有取得太大成功 Mack3 Line Item Journal Time 14 22 33 Date 03 10 2015 Panteni Ledger 1L
  • Jquery随机单词不重复

    我需要在 div 中显示随机单词而不重复该单词 随机单词将每隔随机秒 3 5 秒 附加一个 div 如果数组中的所有值都显示在 div 中 则会发出警报 例子 b a c d ALERT DONE Not b a b c d d a a c
  • 无法聚焦 Web 元素来发送密钥

    我有一组测试 需要登录然后执行搜索 我的应用程序是 Angular JS 我正在起诉 Protractor 事实上 我的测试工作正常 直到我收到我的应用程序的新套件 并且此时我的所有测试都失败了 element by id mainGlob
  • C# 访问另一个用户的注册表

    我当前使用的 Windows 服务有问题 基本上 我将一些值存储在HKCU注册表 来自以管理员身份运行的 GUI 工具 并从该 GUI 中启动一项服务 该服务使用SYSTEM帐户来运行 我相信这是我的问题 我无法访问服务中使用 GUI 工具
  • 从命令行将 JAR 依赖项与可执行 JAR (Über JAR) 捆绑在一起

    我正在尝试从命令行创建可执行 jar JAR 中的主类具有我已打包到另一个普通 JAR 文件中的依赖项 我想将依赖项 JAR 与可执行 JAR 打包在一起 以便提供单个 JAR 文件 到目前为止我已经尝试过以下内容 依赖Hello clas
  • C++ 和抽象类中的继承

    我在正确处理存在抽象类的方法重写时遇到问题 在我的类层次结构中 我会尝试解释一下 class AbstractClass public virtual void anyMethod 0 class A public AbstractClas
  • 使用 WinSCP .NET 未找到方法异常 (EventWaitHandle..ctor)

    我正在尝试使用 PowerShell 和 WinSCP NET 程序集连接到 SFTP 服务器 代码无法打开会话 session Open sessionOptions 在我发现的日志中 Exception System MissingMe
  • 每个版本的 IE 在新窗口中打开链接

    我一直在设计一个网站 并使用 Safari 和 Chrome 进行大部分测试 我刚刚尝试测试 Firefox 也很顺利 让 IE 来解决吧 由于某种原因 对于从 IE 6 到 IE 10 的每个版本 每个链接都会打开一个新窗口 在 IE 1
  • 将文本包裹在圆形 div 内[重复]

    这个问题在这里已经有答案了 我想完成这样的事情 我尝试创建一个 div 并给它一个border radius of 50 问题是文本溢出了圆角 我怎样才能做到这一点 以便整个圆圈可以被填满而不溢出 那这个呢 div border 1px s
  • XML 在 python 中行走[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我是 python 新手 想了解解析
  • Python 多处理作业到 Celery 任务但 AttributeError

    我做了一个像这样的多处理函数 import multiprocessing import pandas as pd import numpy as np def apply df args df func kwargs args retur
  • 为什么 x86-64 System V 调用约定在寄存器中传递参数而不是仅在堆栈中传递参数?

    为什么 32 位 C 将所有函数参数直接压入堆栈 而 64 位 C 将前 6 个参数放入寄存器 其余参数压入堆栈 所以 32 位堆栈看起来像 arg2 arg1 return address old rbp 虽然 64 位堆栈看起来像 ar
  • 如何解决/处理委托 EXC_BAD_ACCESS 错误?对象C

    我正在编写一个库 iPhone 的 Obj C 我想打包并出售它 所以我显然需要在将其出售之前解决所有设计问题 我还利用这个库来帮助我开发另一个应用程序 我的库很大程度上建立在任务委派的基础上 我的主要功能是启动一个 可能 长时间运行的进程