首页 > 如何解决message sent to deallocated instance 这样的错误?

如何解决message sent to deallocated instance 这样的错误?

这个错误产生应该是,一个消息实例已经被释放,但还向他发送消息导致的。

比如我现在有个ViewViewController 。进入这个页面,我创建一个多线程,请求服务端的数据。

当我离开了这个页面。观察dealloc发现,此时页面已经被释放了。
但那个多线程任务他不知道啊,因为网速慢,他还在傻傻的执行。执行完了,他发出一系列的动作,比如更新页面什么的,因为ViewViewController已经被释放了,所以就出现了那样的错误,造成闪退。不知道应该如何避免或者解决这个问题呢?

----------问题补充-------------

__unsafe_unretained __typeof(self) weakSelf = self;
    
    [self.travelService loadTravelDetailData:^(ApiResponser *apiResponser) {
        
        [weakSelf bindUserValue];
        [weakSelf.myTableView reloadData];
        
        
        
    } failBlock:^(NSError *error) {
       
    }];

原本是这样的,页面退出之后就可以释放。但是会闪退。


现在我索性变成这样。因为循环引用,页面即使切换掉内存也没有被释放。但是不闪退了。
    
    [self.travelService loadTravelDetailData:^(ApiResponser *apiResponser) {
        
        [self bindUserValue];
        [self.myTableView reloadData];
        
        
        
    } failBlock:^(NSError *error) {
        
    }];

-----------
有点搞不清楚状况。比如我查看了wordpress的ios客户端。

 void (^successBlock)(RemoteMedia *media) = ^(RemoteMedia *media) {
        [self.managedObjectContext performBlock:^{
            NSError * error = nil;
            Media *mediaInContext = (Media *)[self.managedObjectContext existingObjectWithID:mediaObjectID error:&error];
            if (!mediaInContext){
                DDLogError(@"Error retrieving media object: %@", error);
                if (failure){
                    failure(error);
                }
                return;
            }
            
            [self updateMedia:mediaInContext withRemoteMedia:media];
            mediaInContext.remoteStatus = MediaRemoteStatusSync;
            [[ContextManager sharedInstance] saveContext:self.managedObjectContext withCompletionBlock:^{
                if (success) {
                    success();
                }
            }];
        }];
    };

到处都是self,而不是weak。这样不会造成循环引用吗?


这边用__unsafe_unretained并没什么好处

不如用__weak, 这样你可以检查对象是否还在(如果对象不在了, 弱引用的值会变成nil)

后一个写法中, 如果self不引用(直接或间接)那个块, 就不是循环引用. 这样写会造成self更晚释放(不要这样写),不会因循环引用让self永远不释放.


循环引用是当一个object1强引用了另一个object2,而这个object2同时又强引用了object1,这时由于俩个object引用计数都不为0,从而都无法释放内存。。。

拿你的最后一个block举例。。。因为self没有强引用block,所以在block中强引用self是没有关系的!

另外,_unsafe_unretained与_weak的区别在于当内存释放后前者指针不会销毁,会成为野指针,所以对野指针调用的话,会crash..一般消除循环引用都使用_weak或者手动置block为nil

对于你多线程访问UIViewController的问题,可以将UIViewController消失时,取消线程访问。。或者将UIViewController延迟释放。。。

【热门文章】
【热门文章】