[英]Child View Controller loses delegate after Presenting and Dismissing Modal View
[英]Delegate method not called after dismissing modal view controller
我正在使用NSURLSessionDataTask
從我的JsonClient
類中的URL中檢索JSON,此類具有委托協議,以通知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工作正常。 但是由於某種原因,在我的第一個視圖控制器中沒有調用委托方法。 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
為什么不調用第一個視圖控制器ViewController
的委托方法?
除非JsonClient
是一個Singleton,而你不告訴我們,你要創建的兩個實例JsonClient
,一個在viewWillAppear
的方法ViewController
,另一個在getJsonData
的方法ViewController2
。
這兩個實例分別跟蹤其委托,而您只需要設置其中一個即可。 第二個是單擊ViewController2
的按鈕時調用的,它永遠不會設置其委托,因此它的默認值為nil
,發送給nil
消息沒有任何作用。
您需要類似:
@implementation ViewController2
- (IBAction)getJsonData:(id)sender {
JsonClient *jsonClient = [[JsonClient alloc] init];
jsonClient.delegate = otherViewController;
[jsonClient fetchJsonData];
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.