当我的 ViewController 是导航应用程序崩溃时,AFURI SessionManager

Posted

技术标签:

【中文标题】当我的 ViewController 是导航应用程序崩溃时,AFURI SessionManager【英文标题】:AFURLSessionManager when my ViewController was navigated app crashed 【发布时间】:2017-08-19 07:03:52 【问题描述】:

我在 Objective-C ios 的 AFURLSessionManager 中遇到问题。我有 2 个 viewController 并使用 AFURLSessionManager 从服务器获取数据。

当用户导航到具有 AFURLSessionManager 请求的 viewContoller2 并且用户的网络非常糟糕并按下返回按钮时,AFURLSessionManager 想要调用委托,崩溃并显示 EXC_BAD_ACCESS(code=EXC_I386_GPFLT)

当我导航到 viewController 时,AFURLSessionManager 任务完成较晚,并且 viewController 被用户更改,AFURLSessionManager 尝试调用内存中不存在的委托。

有人有解决这个问题的想法吗?

这是请求代码:

- (void) getData

    NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"GET" URLString:@"http://----------" parameters:nil error:nil];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

    req.timeoutInterval= 15;
    [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [req setValue:@"application/json" forHTTPHeaderField:@"Accept"];

    self.dataTask = [manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error)
     

         if (!error)
         
             NSLog(@"Reply JSON >>>>>> responseObject <<<<<: %@", responseObject);


             if ([responseObject isKindOfClass:[NSDictionary class]])
             
                 if (self.delegate && [self.delegate respondsToSelector:@selector(success:)]) 
                     [self.delegate success:responseObject];
                 
                 //                  self.colorView.backgroundColor = [UIColor blueColor];
                 return;
             
             else
             
                 NSLog(@"Error No dictionary: %@, %@, %@", error, response, responseObject);
                 
                     //                      self.colorView.backgroundColor = [UIColor redColor];
                     [self.delegate error:error];
                     return;
                 

             
         
         else
         
             NSLog(@"Error: %@, %@, %@", error, response, responseObject);
             [self.delegate error:error];
             return;

         

     ];

    [self.dataTask resume];

    if (self.cancelRequest) 
        [self.dataTask cancel];
    

头文件:

@protocol WebServicesDelegate <NSObject>

- (void) success:(NSDictionary *) dic;
- (void) error:(NSError *) error;

@end

@interface WebServices : NSObject

@property (assign,nonatomic) id<WebServicesDelegate> delegate;
@property (nonatomic) BOOL cancelRequest;

-(void) setCancelRequest:(BOOL)cancelRequest;
//+(instancetype) shareInstance;

- (void) getData;

@end

提前致谢

【问题讨论】:

你能展示一些你试过的代码吗! 更新我的问题并输入我的代码 请用崩溃日志更新 ypur 问题。 您正在调用委托,因此请检查 responseObject 是否为 nil,如果没有,则在获取 responseObject 之前调用委托,您将返回到崩溃的视图控制器 应用程序崩溃在哪一行? [self.delegate 成功:responseObject];或 [self.delegate error:error]; 【参考方案1】:

调试 self.delegate 是什么。它绝对不是零,否则它不会崩溃。

它崩溃是因为 self.delegate 不是 NSObject 子类。它要么是标量,要么是一些垃圾值。

我猜你在声明委托时使用了assign 而不是weak,因为它已被分配,所以会导致指针悬空。

编辑(问题更新后) 改变

@property (assign,nonatomic) id<WebServicesDelegate> delegate;

@property (weak,nonatomic) id<WebServicesDelegate> delegate;

【讨论】:

我进入我的头文件,我的委托是NSObject并赋值 这就是它崩溃的原因。将分配更改为弱。【参考方案2】:

问题可能与self 有关,因为您的webservice 是异步的,因此当响应到来时,您已经通过弹出或关闭删除了该视图控制器

你应该使用__weak typeof(self) weakSelf = self;

self的地方使用weakSelf

希望对解决你的问题有所帮助

【讨论】:

我认为它可以帮助我,我尝试使用它。谢谢老兄 它不会崩溃,可能会导致内存泄漏但不会崩溃。 @HusseinHabibiJuybari 我已经多次遇到这种问题。如果有异步任务正在进行并且机会为零,我们应该每次都保持弱引用!并且始终保持代表弱 @MikeAlter:我知道你是对的,但它们不会导致崩溃。 OP 使用的是assign而不是weak,当保存在该委托中的引用变为零时,它会导致一个悬空指针。 @HusseinHabibiJuybari 当你 .正在那个块中做 UI 东西(self 的属性),即用一些响应更改标签值不会再崩溃!

以上是关于当我的 ViewController 是导航应用程序崩溃时,AFURI SessionManager的主要内容,如果未能解决你的问题,请参考以下文章

仅在一个 ViewController 中更改导航栏属性

来自 AppDelegate 的当前 viewController 崩溃/空屏

通过导航控制器推送 Viewcontroller,显示黑屏

使用 TableView 向视图控制器添加导航

如果我使用 TabBar Navigation,如何从 AppDelegate 调用 viewcontroller 方法

Viewcontroller 堆栈理解问题