ios - 解除模态视图 Controller 后未调用委托(delegate)方法

标签 ios objective-c json nsurlrequest nsurlsession

我正在使用 NSURLSessionDataTask 从我的 JsonClient 类中的 url 检索 JSON,该类有一个委托(delegate)协议(protocol)来通知 json 任务何时完成。

JsonClient.h

#import <Foundation/Foundation.h>

@protocol JsonDelegate <NSObject>
- (void)jsonFetchComplete;
@end

@interface JsonClient : NSObject

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

- (void)fetchJsonData;

@end

JsonClient.m

#import "JsonClient.h"

@implementation JsonClient

- (void)fetchJsonData {

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    NSString *urlString = @"http://api.kivaws.org/v1/loans/search.json?status=fundraising";
    urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //urlString = [urlString stringByAppendingString:@".json"];

    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:10];

    NSURLSession *session = [NSURLSession sharedSession];

    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                if (error) {

                                                    NSLog(@"error: %@",error.localizedDescription);

                                                    dispatch_sync(dispatch_get_main_queue(), ^{
                                                        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

                                                        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"ERROR"
                                                                                                        message:error.localizedDescription
                                                                                                       delegate:self
                                                                                              cancelButtonTitle:@"Cancel"
                                                                                              otherButtonTitles:nil];
                                                        [alert show];
                                                    });

                                                } else {
                                                    NSLog(@"got data");

                                                    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

                                                    NSError *jsonerror = nil;

                                                    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonerror];

                                                    dispatch_sync(dispatch_get_main_queue(), ^{
                                                        NSLog(@"json is \n %@",dict);
                                                        [self.delegate jsonFetchComplete];
                                                        NSLog(@"done");
                                                    });
                                                }
                                            }];
    [task resume];
}

@end

获取 json 工作正常。但是由于某种原因,在我的第一个 View Controller 中没有调用委托(delegate)方法。 ViewControllerViewController2 提供模态转场。 ViewController2 中的按钮在点击时获取 json 并返回到第一个 ViewController

ViewController.m

#import "ViewController.h"
#import "JsonClient.h"

@interface ViewController () <JsonDelegate>
@property (weak,nonatomic) IBOutlet UILabel *label;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.label.text = @"Loaded VC";
}

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"view will appear");

    JsonClient *jc = [[JsonClient alloc] init];
    jc.delegate = self;
}

// delegate method from JsonClient
- (void)jsonFetchComplete {
    NSLog(@"fetch complete");
    self.label.text = @"Completed!";
}

- (IBAction)toHome:(UIStoryboardSegue *)segue {
    // unwind segue
}

@end

ViewController2.m

#import "ViewController2.h"
#import "JsonClient.h"
#import "ViewController.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (IBAction)getJsonData:(id)sender {

    JsonClient *jsonClient = [[JsonClient alloc] init];
    [jsonClient fetchJsonData];

    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

为什么第一个 View Controller ViewController中的delegate方法没有被调用?

最佳答案

除非 JsonClient 是单例,并且您没有告诉我们,您正在创建两个 JsonClient 实例,一个在 viewWillAppear ViewController 的方法和 ViewController2getJsonData 方法中的另一个方法。

这两个实例分别跟踪它们的委托(delegate),而您只设置了其中一个。第二个,当您单击 ViewController2 中的按钮时被调用的那个,从未设置其委托(delegate),因此它默认为 nil,并将消息发送到 nil 什么都不做。

你需要这样的东西:

@implementation ViewController2

- (IBAction)getJsonData:(id)sender {

    JsonClient *jsonClient = [[JsonClient alloc] init];
    jsonClient.delegate = otherViewController;
    [jsonClient fetchJsonData];

    [self dismissViewControllerAnimated:YES completion:nil];
}

@end

关于ios - 解除模态视图 Controller 后未调用委托(delegate)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20036532/

相关文章:

ios - 多个 UICollectionViewCells 内的 UIButton 无法正常工作

ios - Realm 结果对象类型

ios - 我应该如何在 iOS 项目中存储本地化字符串?

ios - NSString hasPrefix : vs hasSuffix: which is less expensive?

javascript - 解析带有正斜杠的 json 字符串 - javascript

ios - navigationController 为 nil,当推送 viewcontroller 时

iOS Objective-Zip 损坏问题

objective-c - NSNumber 作为 NSDictionary 的键

java - 如何将java数据放入json文件中?

python - 使用 Bottle 的自定义插件将日期时间作为 JSON 返回?