升级到iOS 9后登录流程失败

4

将我的应用程序升级到iOS9后,我的应用程序出现了一个错误,错误消息如下:

: objc[344]: 无法对类LoginVC的实例(0x15919e00)进行弱引用。这个对象可能已经释放过多次,或者正在被解除分配。

以下是发生此错误的函数:

-(void)dismissLogin {
self.isLoggingIn = NO;
[self stopLoginAnimation];
[self dismissViewControllerAnimated:YES completion:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.appDelegate setLoginVC:nil];
[self.view removeFromSuperview];
//[APPDEL selectTabBar];
}

应用程序在登录界面卡住,并且无法切换到下一个界面。
这个错误在iOS8中并不存在。 有人可以帮助解决这个问题吗?

你尝试过在运行应用程序时使用调试器来检查逻辑吗?这个错误发生在应用程序的特定行吗(如果是,请发布一些代码)? - Robotic Cat
这个错误只出现在设备上,而不是在Xcode上。我正在设置我的开发者许可证以从设备进行调试。你有任何想法为什么会发生这种情况吗? - eureka19
我不知道,如果没有代码参考,我只能猜测。但是,暗示你的目标图逻辑是错误的。在某个地方,当你想让LoginVC保持活跃时,它被释放了。这是一个逻辑问题,但你需要调试找出它发生的位置。在你的类的dealloc方法中记录日志,以了解你的对象何时被销毁。 - Robotic Cat
这可能与iOS 9+ / OS X 10.11+中行为不可解的变化有关,其中将正在进行解除分配的对象分配给弱变量会导致崩溃。 - user102008
2个回答

4

请确保您未使用正在被释放的实例。

我也遇到了同样的问题。在iOS 8中没有出现这个问题,但在iOS 9中出现了。因为我重写了setDelegate方法,像这样:

-(void)setDelegate:(id<UICollectionViewDelegate>)delegate{
    _internalDelegate = delegate;
    [super setDelegate:self];
}

iOS 9中,操作系统在释放内存时将delegate设置为nil,但我却将其设置为self。所以快速修复方法是:

-(void)setDelegate:(id<UICollectionViewDelegate>)delegate{
    _internalDelegate = delegate;
    if (delegate) {
        //Set delegate to self only if original delegate is not nil
        [super setDelegate:self];
    }else{
        [super setDelegate:delegate];
    }
}

1
对我来说,错误只出现在iOS 9设备上,而不是iOS 9模拟器上。如果我的代码存在一些内存问题,我不明白为什么它能在模拟器上运行。 - eureka19

0

我最近遇到了这个问题,这让我得出了结论。我对上面提供的解决方案唯一的问题是,如果你需要子类在其internalDelegate为nil时获得功能,它就行不通。

这是我想出的解决方案,既可以防止崩溃,又可以使功能即使在nil internalDelegate的情况下存在。我觉得我应该分享一下,以防其他人也遇到了这个问题。

  1. 创建第二个内部属性,我称之为weakSelf
@property (nonatomic, weak) LoginVC *weakSelf;
  1. 在任何初始化方法中,将weakSelf设置为self
 - (id)init {
    if ((self = [super init])) {
        self.weakSelf = self;
    }
}
  1. 更新委托方法
- (void)setDelegate:(id)delegate {
    _internalDelegate = delegate;
    [super setDelegate:self.weakSelf];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接