Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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 如果我释放,我就无法访问,如果我保留,我就会泄漏_Iphone_Objective C_Cocoa Touch - Fatal编程技术网

Iphone 如果我释放,我就无法访问,如果我保留,我就会泄漏

Iphone 如果我释放,我就无法访问,如果我保留,我就会泄漏,iphone,objective-c,cocoa-touch,Iphone,Objective C,Cocoa Touch,我有一个视图控制器,我正试图推到导航堆栈上。我用一个局部变量创建控制器,设置它,然后将它分配给属性。然后,如果我释放该变量,我将获得EXE\u BAD\u访问权限。如果我保留(或自动释放)它会泄漏 CustomTVC* controller = [[CustomTVC alloc]initWithStyle:UITableViewStyleGrouped]; controller.managedObjectContext = self.managedObjectContext; self.ta

我有一个视图控制器,我正试图推到导航堆栈上。我用一个局部变量创建控制器,设置它,然后将它分配给属性。然后,如果我释放该变量,我将获得EXE\u BAD\u访问权限。如果我保留(或自动释放)它会泄漏

CustomTVC* controller = [[CustomTVC alloc]initWithStyle:UITableViewStyleGrouped];
controller.managedObjectContext = self.managedObjectContext;

self.tableViewControllerIvar = controller;

[self.navigationController pushViewController:self.tableViewControllerIvar animated:YES];
 //[controller autorelease]; or [controller release]; or nothing
下面就是如果我释放

  • 以上代码是通过按下导航栏中的添加按钮触发的
  • 视图被推送,一切都很好。在新视图中,我可以一次又一次地推送更多视图,没有问题……除非
  • 我返回到导航堆栈的根视图。(上述代码的来源)
  • 现在,如果我再次向下钻取到第二个视图,然后尝试推另一个视图,它会崩溃

  • 编辑:当我将第三个控制器推到堆栈上时,我有一种感觉,好像出了什么问题。通过推送,它将一个新对象插入到托管对象上下文中,这将导致fetchedresultscontroller更新tableview。那里的某个地方可能有一个坏指针。我将使用它并发布结果

    编辑:5/16

    正在日志中获取此错误消息

    *-[CustomTVC controllerWillChangeContent:]:发送到解除分配实例0x187270的消息


    只有在我从堆栈中弹出CustomTVC(返回到导航根视图控制器)后,才会发生这种情况。只要我不弹出CustomTVC,我就可以推送并保存所有我想要的内容。

    autorelease
    应该可以完成这项工作。分配
    tableViewControllerIvar
    时,只需调用
    [controller autorelease]
    。这应该会解决这个问题

    CustomTVC* controller = [[CustomTVC alloc]initWithStyle:UITableViewStyleGrouped];
    controller.managedObjectContext = self.managedObjectContext;
    
    self.tableViewControllerIvar = [controller autorelease];
    
    [self.navigationController pushViewController:self.VCTVC animated:YES];
    

    如果您仍然获得EXE\u BAD\u访问权限,那么肯定发生了其他事情。您是否已确认此代码在多次运行时会导致错误访问?

    您正在将控制器分配给tableViewControllerIvar

     self.tableViewControllerIvar = controller;
    
    您正在释放控制器,因此需要将其保留在上述行中

     self.tableViewControllerIvar = [controller retain];
    

    当您使用完“tableViewControllerIvar”后,只需将其释放,之后将不会出现任何泄漏。

    修复它。必须在viewDidLoad中将获取的结果控制器委托设置为nil

    - (void)dealloc
    {
        self.fetchedResultsController.delegate = nil;
        [_fetchedResultsController release];
        [_managedObjectContext release];
        [super dealloc];
    }
    
    似乎罪魁祸首是(根据僵尸文书):

    [NSFetchedResultsController(私有方法)\u managedObjectContextDidChange:]


    编辑:终于花了些时间来弄清楚如何正确地将代码放在这里(我很懒)

    你应该能够释放一个你正在推到NVC堆栈中的VC。但您的代码显示您正在释放变量“controller”,但在按下变量“VCTVC”之后?如果改为按“controller”(控制器)会怎样?请显示
    tableViewControllerIvar
    @property(非原子,保留)CustomTVC*tableViewControllerIvar的
    @属性声明@samvermette我实际上在前后都试过推它,结果仍然相同(奇怪)。顺便说一句,我在行中编辑了一个错误,将新控制器推到导航堆栈(从VCTVC到tableViewController)。设置属性与仅设置指针的值不同。它调用一个方法,该方法应适当地处理属性声明的保留计数。像第二行这样的代码几乎总是错误的;要么是retain导致了泄漏,要么是tableViewControllerIvar声明错误。正如我所说,无论哪种方式,这都是错误的修复。如果该属性不是保留属性,那么正确的解决方法是将其设置为保留属性,而不是拥有声称不保留但实际上“拥有”保留计数的属性。当我将第三个控制器推到堆栈上时,我感觉出了问题。通过推送,它将一个新对象插入到托管对象上下文中,这将导致fetchedresultscontroller更新tableview。那里的某个地方可能有一个坏指针。我将使用它并发布结果。因此我猜将委托设置为nil是一种很好的做法,以防止出现这种情况?根据,NSFetchedResultsController的委托是一个“assign”属性,因此不将其设置为nil不应导致泄漏。你重新申报保留了吗?通常的做法是,为了避免保留循环。是的,在
    dealoc
    上将代理设置为
    nil
    ,总是一个好主意。你永远不知道是否有人仍然保留具有委托属性的对象(即使你确实知道,你可能会在将来更改它,并且忘记它可能会引起麻烦)。是的,很有趣,几天前,我在这里看到一个问题,问到是否应该将委托设置为零。大多数答案/评论都说这无关紧要。