我正在使用 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)方法。 ViewController
为 ViewController2
提供模态转场。 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
的方法和 ViewController2
的 getJsonData
方法中的另一个方法。
这两个实例分别跟踪它们的委托(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/