objective-c – 尝试在单例中更改变量但它保持可为空

刚刚开始编写 objective-c编程,现在我遇到了自己无法解决的问题.我正在从异步请求接收数据并尝试将其转发为单例,但它没有改变.

这是我试图存储我的数据的地方
Data.h

#import <Foundation/Foundation.h>
@interface Data : NSObject
@property (nonatomic,strong) NSDictionary *products;
-(void)setProducts:(NSDictionary *)value;
@end

Data.m

#import "Data.h"

@implementation Data

+(Data *)sharedInstance
{
    static Data *_sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate,^{
        _sharedInstance = [[Data alloc] init];
    });
    return _sharedInstance;
}

- (id)init {
    self = [super init];
    if ( self )
    {
        _products = [[NSDictionary alloc] init];
    }
    return self;
}

@end

这是我从服务器接收数据的类:
ConnectionService.m

- (void)getProductsWithCompletion:(void (^)(NSDictionary *products))completion
{
    Nsstring *urlString = [Nsstring stringWithFormat:@"serverurl",[[AppDelegate instance]getUrl]];
    NSURL *url = [NSURL URLWithString:urlString];

    NSURLSessionDataTask *getData = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data,NSURLResponse *response,NSError *error){
        Nsstring *rawJson = [[Nsstring alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSDictionary *value = [rawJson JSONValue];
        completion(value);
    }];
    [getData resume];
}

这是我正在调用请求并尝试将其传递给单例的类:
viewController.m

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:YES];
    [[ConnectionService instance] getProductsWithCompletion:^(NSDictionary *products) {
        [Data sharedInstance].products = products;
        NSLog(@"products: %@",[[Data sharedInstance] products]);//all is working,products contains data
    }];
    // checking received data 
    NSDictionary *tmp = [[Data sharedInstance] products];
    NSLog(@"tmp: %@",tmp); //Now it's null
}

解决方法

问题在于请求是异步的,并且事情没有按照您期望的顺序发生:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:YES];
     [[ConnectionService instance] getProductsWithCompletion:^(NSDictionary *products) {
        // (2)
        [Data sharedInstance].products = products;
        NSLog(@"products: %@",[[Data sharedInstance]products]);//all is working,products contains data
    }];


    // (1)
    NSDictionary *tmp = [[Data sharedInstance]products];
    NSLog(@"tmp: %@",tmp); //Now it's null
}

在您发布的代码中,(1)将在(2)之前发生.这是因为(2)是完成块的一部分,并且一旦网络请求完成并且所有数据都已被解析并准备好使用,就会设置为运行.虽然该异步请求已准备好并在后台线程中运行,但主线程((1))会在请求发生之前继续并执行.

解决此问题,请将日志记录移至完成例程,或者只需删除(1).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...