لم يتم استدعاء طريقة التفويض بعد استبعاد وحدة التحكم في العرض المشروط
-
21-12-2019 - |
سؤال
انا استخدم NSURLSessionDataTask
لاسترداد JSON من عنوان url في ملفي JsonClient
فئة، تحتوي هذه الفئة على بروتوكول مفوض لإعلامك عند اكتمال مهمة 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