【问题标题】:How to work with NSOperation Queue in objective c?如何在目标 c 中使用 NSOperation Queue?
【发布时间】:2017-07-12 06:31:07
【问题描述】:

以下代码出现错误,我正在使用 NSOperationQueue 从服务器获取发布数据。在登录时,我想从服务器获得总共 8 次响应。为此,我正在使用 NSOperationQueue,但它无法正常工作。有时我会收到此错误

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

self.operationQueue = [NSOperationQueue new];

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                        selector:@selector(getDataFromServer2)
                                                                          object:nil];

[self.operationQueue addOperation:operation];

// The same story as above, just tell here to execute the colorRotatorTask method.
operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(getDataFromServer3)
                                                   object:nil];
[self.operationQueue addOperation:operation];

operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(getDataFromServer4)
                                                   object:nil];
[self.operationQueue addOperation:operation];

operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(getDataFromServer5)
                                                   object:nil];
[self.operationQueue addOperation:operation];

operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(getDataFromServer6)
                                                   object:nil];
[self.operationQueue addOperation:operation];

operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(getDataFromServer7)
                                                   object:nil];
[self.operationQueue addOperation:operation];

operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                 selector:@selector(getDataFromServer8)
                                                   object:nil];
[self.operationQueue addOperation:operation];

我的 JSON 代码是

- (void) getDataFromServer2 {

NSString *str = [NSString stringWithFormat:@"http://***********?”];

NSLog(@"%@", str);

self.urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
self.url = [NSURL URLWithString:str];
self.urlReq = [[NSMutableURLRequest alloc]initWithURL:self.url];
[self.urlReq setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[self.urlReq setHTTPMethod:@"POST"];

NSString *post = [[NSString alloc]initWithFormat:@“*=&&”];

NSLog(@“Post : %@", post);

NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long) [postData length]];
[self.urlReq setValue:postLength forHTTPHeaderField:@"Content-Length"];
[self.urlReq setHTTPBody:postData];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
    self.dataTask = [self.urlSession dataTaskWithRequest:self.urlReq completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        if (!(data == nil)) {

            NSError *error;
            self.loginDic2 = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
            NSLog(@"%@", error);

            self.integer2 = [[self.loginDic2 objectForKey:@"id"] count];
            NSLog(@"self.integer2 : %lu", self.integer2);
            NSLog(@"Login Dic2 : %@", self.loginDic2);

            if ([[self.loginDic2 objectForKey:@"status"] isEqualToString:@"SUCCESS"]) {

                    self.ID = [[NSMutableArray alloc]init];
                    self.m = [[NSMutableArray alloc]init];

                dispatch_async(dispatch_get_main_queue(), ^{

                    for (int i=0; i<self.integer2; i++) {

                        [self.ID addObject:[[[self.loginDic2 objectForKey:@“d”] objectAtIndex:i] objectForKey:@"id"]];
                        [self.m addObject:[[[self.loginDic2 objectForKey:@“d”] objectAtIndex:i] objectForKey:@"m"]];

                    }

                    NSLog(@"cast_nm : %@", self.m);


                    [self.defaults setObject:self.cast_nm forKey:@"m"];
                    [self.defaults synchronize];

                });

            } else {

                NSString *str = [self.loginDic2 objectForKey:@"error_code"];

                if ([str isEqualToString:@"104"]) {
                    self.noRecordsFound = @"No Records Found.";
                } else {
                    self.noRecordsFound = @"Invalid Parameters.";
                }

                UIAlertController * alert = [UIAlertController alertControllerWithTitle : @"Message"
                                                                                message : self.noRecordsFound
                                                                         preferredStyle : UIAlertControllerStyleAlert];

                UIAlertAction * ok = [UIAlertAction
                                      actionWithTitle:@"OK"
                                      style:UIAlertActionStyleDefault
                                      handler:^(UIAlertAction * action)
                                      { }];

                [alert addAction:ok];

                dispatch_async(dispatch_get_main_queue(), ^{
                    [self presentViewController:alert animated:YES completion:nil];

                });

            }

        } else {

            UIAlertController * alert = [UIAlertController alertControllerWithTitle : @"Message"
                                                                            message : @"No server response."
                                                                     preferredStyle : UIAlertControllerStyleAlert];

            UIAlertAction * ok = [UIAlertAction
                                  actionWithTitle:@"OK"
                                  style:UIAlertActionStyleDefault
                                  handler:^(UIAlertAction * action)
                                  { }];

            [alert addAction:ok];

            dispatch_async(dispatch_get_main_queue(), ^{
                [self presentViewController:alert animated:YES completion:nil];

            });

        }

    }];  [self.dataTask resume];
});
}

我使用相同的代码 8 次 ....

【问题讨论】:

  • 如果你使用 NSURLSession,我认为你不需要使用 NSOperationQueue,因为它是一个 operationQueue。将 delegateQueue 设置为 nil 使其成为默认类型(即串行队列)。
  • 但是在数组中存储值时出现错误。这就是我使用队列的原因
  • 可能是其他原因造成的。我的猜测是它不是由于不使用 NSOperationQueue 引起的。如果执行此代码 8 次,则其中 8 次将串行运行,只是顺序未知。所以你需要手动处理。
  • 这个和NSOperationQueue没有关系,在self.loginDic2处下个断点 = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];并检查 loginDic2 是否实际上是 JSON 对象数组!我相信它的 nil 因此崩溃可能是服务器没有发送数据或发送的数据不是 JSON 数组,仅此而已
  • 上面的 Gencode 注释是正确的

标签: ios objective-c json nsoperation nsoperationqueue


【解决方案1】:

问题是self.ID addObjectself.m addObject。有时您尝试插入的对象似乎是nil,而您无法将nil 插入到数组中。

我在您的代码中看到的其他问题是您在块内使用了对 self 的强引用,这可能会导致内存泄漏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多