iOS - 消费API时的问题 - dispatch_async

时间:2016-02-12 06:30:14

标签: ios objective-c dispatch-async

我试图获得API工作的基本原型。我有网络服务设置,现在我正在尝试让iOS应用程序请求数据并将其显示在表格中。这是非常基本的,但是,数据的随机部分在表中显示为null,我无法找到共同的线程。

但基本上,我调用了这个API,我解析数据,我使用StopCollection类来createItem(类型为StopItem)并将其添加到{{在NSMutableArray中的1}}。然后在StopCollection中,我将该数组用作数据源。

数据来自API。我可以添加MainTableViewController就好了。但是,似乎在NSMutableArray中,一旦我到达以下行,我就无法访问数组中的相同数据,并且值为MainTableViewController

null

以下是我正在使用的内容:

MainTableViewController.m

dispatch_async(dispatch_get_main_queue(), ^{
   [self.tableView reloadData];
});

StopCollection.m

#import "MainTableViewController.h"
#import "StopCollection.h"
#import "StopItem.h"

@interface MainTableViewController ()

@property (nonatomic, strong) NSURLSession *session;

@end

@implementation MainTableViewController

- (instancetype)init
{
    self = [super initWithStyle:UITableViewStylePlain];
    if (self) {
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        _session = [NSURLSession sessionWithConfiguration:config
                                                 delegate:nil
                                            delegateQueue:nil];
        [self fetchFeed];
    }

    return self;
}

- (void)fetchFeed
{
    NSString *requestString = @"http://nexttrain.dev/station?include=stopTime";
    NSURL *url = [NSURL URLWithString:requestString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

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

                            NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data
                                                                                           options:0
                                                                                             error:nil];
                                for(NSDictionary *stop in jsonObject[@"data"])
                                {
                                    for (NSDictionary *stopTime in stop[@"stopTime"][@"data"]) {

                                    [[StopCollection sharedStore] createItem:stop[@"station"]
                                                                   withRoute:stopTime[@"route"]
                                                                withHeadsign:stopTime[@"trip"]
                                                             withArrivalTime:stopTime[@"arrival_time"]];
                                    NSLog(@"%@", stop[@"station"]);
                                    }
                                }

                                dispatch_async(dispatch_get_main_queue(), ^{
                                    [self.tableView reloadData];
                                });
                            }];

    [dataTask resume];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.tableView registerClass:[UITableViewCell class]
           forCellReuseIdentifier:@"UITableViewCell"];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[[StopCollection sharedStore] stops] count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                            forIndexPath:indexPath];

    NSArray *allStops = [[StopCollection sharedStore] stops];
    StopItem *stop = allStops[indexPath.row];

    NSString *formattedText =  [NSString stringWithFormat:@"%@ - %@ - %@", stop.station, stop.route, stop.arrivalTime];
    cell.textLabel.text = formattedText;

    cell.textLabel.font = [UIFont systemFontOfSize:12];

    return cell;
}

StopCollection.h

#import "StopCollection.h"
#import "StopItem.h"

@interface StopCollection()

@property (nonatomic) NSMutableArray *privateStops;

@end

@implementation StopCollection

// Override Accessor for Stops, and return from privateStops.
- (NSArray *)stops
{
    return [self.privateStops copy];
}

// Singleton Access to Object.
+ (instancetype)sharedStore
{
    // Static will be Strong and will remain.
    static StopCollection *sharedStore;
    // Create initial instance.
    if (!sharedStore) {
        sharedStore = [[self alloc] initPrivate];
    }
    // Return instance if exists.
    return sharedStore;
}

// Make defualt init inaccessible.
- (instancetype)init
{
    // Throw Exception if accesssed.
    [NSException raise:@"Singleton"
                format:@"Use + (instancetype)sharedStore"];
    return nil;
}

// Private initializer will call Super init.
- (instancetype)initPrivate
{
    self = [super init];

    if (self) {
        _privateStops = [[NSMutableArray alloc] init];
    }

    return self;
}

- (void)createItem:(NSString *)station withRoute:(NSString *)route withHeadsign:(NSString *)headsign withArrivalTime:(NSString *)arrivalTime
{    
    StopItem *stop = [[StopItem alloc] initWithStation:station
                                                lattitude:22
                                                longitude:56
                                                    route:route
                                            tripHeadsign:headsign
                                           arrivalTime];

    [self.privateStops addObject:stop];
}



@end

StopItem.m

#import <Foundation/Foundation.h>

@interface StopCollection : NSObject

+ (instancetype)sharedStore;
@property(nonatomic, readonly, copy) NSArray *stops;
- (void)createItem:(NSString *)station
         withRoute:(NSString *)route
      withHeadsign:(NSString *)headsign
   withArrivalTime:(NSString *)arrivalTime;

@end

StopItem.h

#import "StopItem.h"

@implementation StopItem

- (instancetype)initWithStation:(NSString *)station lattitude:(NSInteger)lattitude longitude:(NSInteger)longitude route:(NSString *)route tripHeadsign:(NSString *)headsign arrivalTime:(NSString *)arrivalTime
{
    self = [super init];
    if (self) {
        _station = station;
        _lattitude = lattitude;
        _longitude = longitude;
        _route = route;
        _tripHeadsign = headsign;
        _arrivalTime = arrivalTime;
    }

    return self;
}

- (instancetype)init {

    return [self initWithStation:@"Hey" lattitude:0 longitude:0 route:@"" tripHeadsign:@"" arrivalTime:[[NSString alloc] init]];
}

@end

这是我正在使用的JSON数据集:

@interface StopItem : NSObject

@property (nonatomic, weak) NSString    *station;
@property (nonatomic)       NSInteger   lattitude;
@property (nonatomic)       NSInteger   longitude;
@property (nonatomic, weak) NSString    *route;
@property (nonatomic, weak) NSString    *tripHeadsign;
@property (nonatomic, weak) NSString    *arrivalTime;

- (instancetype)initWithStation:(NSString *)station
                      lattitude:(NSInteger)lattitude
                      longitude:(NSInteger)longitude
                          route:(NSString *)route
                   tripHeadsign:(NSString *)headsign
                    arrivalTime:(NSString *)arrivalTime;

@end

1 个答案:

答案 0 :(得分:0)

这与dispatch无关。这是因为你有weak个属性,只要有可能就会被填满,即当没有引用它们时。在weak模型中将strong更改为copyStopItem,一切正常。