Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何解决/处理委派EXC\u BAD\u访问错误?Obj C_Iphone_Ios_Delegates_Exc Bad Access - Fatal编程技术网

Iphone 如何解决/处理委派EXC\u BAD\u访问错误?Obj C

Iphone 如何解决/处理委派EXC\u BAD\u访问错误?Obj C,iphone,ios,delegates,exc-bad-access,Iphone,Ios,Delegates,Exc Bad Access,我正在编写一个库(适用于iPhone的Obj-C),我想打包并出售它,所以在将其上市销售之前,我显然需要解决任何设计难题。我还利用这个库来帮助我开发另一个应用程序 我的图书馆在很大程度上是建立在任务授权的基础上的。我的主要功能是启动一个(可能)长时间运行的进程,完成后,我在类的委托中调用委托协议方法 另一个复杂的因素是,我通常会安排这项任务每30秒左右启动一次。通常,我使用[self-performSelector:@selector(someMethod:)withObject:nil aft

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

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

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

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

我尝试先检查[[self-Delegate]respondsToSelector:@selector(doSomeDelegateMethod)],但即使是这种访问显然也会抛出EXC\u BAD\u访问

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

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

这似乎给子弹伤打上了创可贴。是的,这次它似乎阻止了我的应用程序崩溃,但我的直觉告诉我这是一个糟糕的解决方案

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

然而,真正让我感到困扰的是,作为一名库开发人员,我还没有找到一种方法来“装箱”我的代码,这样,如果用户没有做正确的事情,代码就不会抛出异常。基本上,我希望有一种方法来实现我的目标:

  • 得到一个请求
  • 去寻找答案
  • 找到答案
  • 尝试返回答案
  • 意识到另一端什么都没有
  • 放弃,自生自灭。(好吧,“自生自灭”可能不会发生,但你明白了。)
  • 有一个有趣的侧重点:

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

    我执行了以下步骤:

  • 构建了我的库的.h/.m文件
  • 生成了我的库的.a输出文件
  • 已将我的库的.a/.h文件导入到另一个项目中
  • 有上述错误
  • 阅读了其中一个.m文件中的代码,该文件应该隐藏在.a文件中
  • 我是不是遗漏了什么?如果它为客户机抛出错误,我真的会冒着暴露整个源代码的风险吗?(这只是一个次要问题,但我在这里相当担心!)

    谢谢你能提供的帮助,帮助我成为一名更好的程序员

    ---编辑---

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

    这里有个问题:如果在长时间的通话中,视野消失了呢?是的,这很棘手,不太可能做到,但我只是让它发生在模拟器上。特别是,这就是为什么我要寻找一种变通方法,让我的代码实现“嘿,这个管道的另一端没有任何东西”,然后优雅地失败。有人吗


    谢谢

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

    • 传统的代理方法(
      UITableViewDelegate
      )要求在离开前清除自己的代理身份。这通常是在委托的
      dealloc
      中通过
      otherObject.delegate=nil
      完成的。不这样做是编程错误。这基本上就是你所看到的。当委托人和委托人的寿命基本相同时,这是常见的模式

    • 另一种方法是
      NSURLConnection
      如何处理:保留您的代理,直到完成。这项工作正常的关键是
      NSURLConnection
      有自己的生命周期,因此retain循环将自动完成
      UITableView
      无法保留其委托,因为这几乎总是会创建一个永久的retain循环。如果你的物体存在一段时间然后消失,那么这是有意义的。通常在这里,委托人的生命周期比委托人短得多,因此retain循环不会造成任何影响

    调用
    performSelector:withObject:afterDelay:
    的任何对象都应始终在其自己的
    dealloc
    中调用
    cancelPreviousPerformRequestsWithTarget:self
    。不过,这与您的代理无关。它应该独立于对象本身
    self.fetchedResultsController.delegate = nil;