个人笔记:读AFNetworking (一)

652 阅读2分钟

自己实现一个网络请求

不借助第三方框架,自己借助苹果的网络请求类去实现,其实也挺简单的。

创建NSURLSession

  • NSURLSessionConfiguration:设置一些信息,包含下载是否可以用4等,这里可以先用默认的。
  • 设置代理:收数据,comple等回调都是走的代理,好像也支持block,这里暂时用delegate吧。
  • delegateQueue: 代理方法回调时所在的线程。

- (void)createSession {
   
   NSOperationQueue* queue = [[NSOperationQueue alloc]init];
   self.myqueue = queue;
   queue.name = @"subthread";
   self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:queue];
   self.baseUrlString = @"https://1z4-devmng2.sho.com/zmd/";
}

NSURLSessionTask

一个网络请求对应一个task,具体看以下代码,我们想要取消一个请求,可以用task.taskIdentifier这个属性,在一个session里,他是唯一的。我这里用一个字典把所有的task以及所对应的收到的NSdata都收集起来。

-(NSUInteger)taskIndentifierCoreWebInterfaceWithPostRequest:(NSString *)requestPath
                                pararms:(NSDictionary *)dict
                                success:(void (^)(NSDictionary *))success
                                failure:(void (^)(NSDictionary *))failure
{
    //@"clienttype=1&language=en&platform=2"
    NSURLSessionTask* task = nil;
    
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",self.baseUrlString,requestPath]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = [AFQueryStringFromParameters(dict) dataUsingEncoding:NSUTF8StringEncoding];
    task = [self.session dataTaskWithRequest:request];
      //  task = [session dataTaskWithURL:[NSURL URLWithString:@"https://1z4-devmng2.myzmodo.com/zmd/common/globalconfig?clienttype=1&language=en&platform=2"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
      //           NSDictionary * result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
      //           NSLog(@"字符串转到data,再转成json%@",result);
      //       }];
    [task resume];
    TaskObject* taskobjc = [[TaskObject alloc]initWithTask:task];
    taskobjc.successBlock = success;
    taskobjc.failureBlock = failure;
    
    [self.taskDic setObject:taskobjc forKey:@(task.taskIdentifier)];
    
    return task.taskIdentifier;
}

- (void)cacelTaskId:(NSInteger)taskId
{
    [self.taskDic[@(taskId)].task cancel];
    [self.taskDic removeObjectForKey:@(taskId)];
}
 

一个block的crash

一个vc push到另一个vc,然后这个vc发起网络请求,请求成功后这个vc的一个block会执行一些操作,但是用户没等到请求完成就返回了,按道理来说,vc释放后为nil,vc.block应该不会crash,但是这里会crash,我打印了一下,此时block是null。发一个消息,会报野指针的崩溃。至于原因,我还没想太明白。

答案:block调用是函数指针,属性跟方法是messageSend,所以block调用要判空 self.name是getter方法, self->_name是直接访问