Popover控制器在iOS 8中被销毁(无)

Popover控制器在iOS 8中被销毁(无),ios,objective-c,uipopovercontroller,Ios,Objective C,Uipopovercontroller,在iOS 7中,我曾在视图控制器(显示在popover中)中定义对popover控制器的弱引用。我使用这个对popover控制器的引用是为了以编程方式消除popover。此外,我还定义了popover控制器的委托,以便跟踪解除事件(popover控制器应添加SmissPopover等) 在iOS 8中,它停止工作。调查表明,在某个点之后,弱参考点指向nil。代理也停止了工作(据我所知,这是因为代理是在popover控制器中定义的,它在显示popover后由于某种原因在iOS 8中被破坏) 通过将

在iOS 7中,我曾在视图控制器(显示在popover中)中定义对popover控制器的弱引用。我使用这个对popover控制器的引用是为了以编程方式消除popover。此外,我还定义了popover控制器的委托,以便跟踪解除事件(
popover控制器应添加SmissPopover
等)

在iOS 8中,它停止工作。调查表明,在某个点之后,弱参考点指向
nil
。代理也停止了工作(据我所知,这是因为代理是在popover控制器中定义的,它在显示popover后由于某种原因在iOS 8中被破坏)

通过将属性更改为
strong
reference,问题得以解决。 对于一些Popover(我有很多),我不得不添加强引用,只是为了让PopoOvercontroller保持活动状态,因为我需要
委托
来工作。这显然是黑客行为。我添加了我并不真正需要也不使用的属性

请你澄清一下这是否是正确的方法。我担心的是,强引用可能会导致内存泄漏。我也不太明白为什么popover控制器在iOS 8中被破坏,而popover仍然在屏幕上

这是具有弱属性的我的视图控制器。将
更改为
以在iOS 8下正常工作后:

@interface TFDSuggestionViewController : UIViewController
...
@property (weak, nonatomic) UIPopoverController *myPopoverController;
...
@end
这是我在调用视图控制器的
prepareforsgue
方法中为属性赋值和委托的方式:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"suggestions"]) {
        TFDSuggestionViewController *suggController = ((TFDSuggestionViewController *)[segue destinationViewController]);
        suggController.myPopoverController = ((UIStoryboardPopoverSegue *)segue).popoverController;
        ((UIStoryboardPopoverSegue *)segue).popoverController.delegate = self;
    }
} 

谢谢你的建议

在过去的手动内存管理中,有一种称为引用计数的方法。它本质上是一个对象被其他对象或应用程序保留(强引用)的次数。在最近的ARC(自动参考计数)中,我们不再需要执行
[对象保留]
[对象释放]
。这些操作由编译器为我们处理

现在谈谈你的情况。弱引用不会增加所引用对象的引用计数。因此,如果在作用域中创建对象,请为其指定弱引用,然后将对象的引用计数保留为0

-(void)SomeMethod
{
    ClassObject *object = [[ClassObject alloc] init];
    //object's internal reference count is now 1

    self.myPopoverController = object;
    //Since myPopoverController is a weak reference, object still has reference count of 1

    //Some other code that does things and stuff.
}
//We just closed the scope, so object's reference count is now 0
//ARC is free to release the object to free it's memory, causing any
//weak references to return nil
在上面的示例中,它显示了一个非常简单的对象生命周期。一旦你了解了生命周期,你就会明白为什么在这种情况下,弱引用对你绝对没有好处

至于为什么它在iOS7中工作而不是在iOS8中工作,我唯一的答案是iOS8在垃圾收集方面可能更高效。如果你在iOS7中运行它一百万次,我相信你会发现至少有一个发生完全相同问题的例子。这是新操作系统使其更为流行的代码中的一个缺陷

如果希望对象保持活动状态,则需要至少有一个对该对象的强引用。唯一的预防措施是,当你打电话解雇你应该零强引用。这样就不会有不利的记忆问题需要解决

还有一点非常重要。
UIPopoverController
与屏幕上可见的对象不同。屏幕上显示的是
UIPOPCovercontroller.view
。视图仍由视图层次结构保留,但控制器需要由您保留,以使其不被释放。一旦
UIPopoverController
被释放,视图的委托将为零,因为
view。委托
也是一个弱引用


研究对象生命周期。它将帮助您避免将来随着操作系统在内存处理方面越来越高效而肯定会出现的垃圾收集问题。

感谢您提供详细的回答(我从iOS 3开始开发,非常了解手动内存管理)!我假设(可能是错误的)popover控制器必须保持活动状态,才能在显示底层视图时控制它。一旦视野消失就被摧毁了。然后使用方法
PopOvercontrollersouldDismissPopOver
进行委托。根据代理名称,我假设popover控制器不仅负责显示,还负责取消popover视图,并且必须保持活动状态才能完成此操作。