[英]iOS - Issue When Consuming API - dispatch_async
我试图获得一个基本的API原型。 我已经设置了Web服务,现在我正在尝试让iOS应用程序请求数据并将其显示在表格中。 这是非常基本的,但是,数据的随机部分在表中显示为null
,并且我无法找到公共线程。
但基本上,我对此API进行了调用,解析了数据,使用StopCollection
类创建了createItem
(类型为StopItem
)并将其添加到StopCollection
的NSMutableArray
中。 然后在MainTableViewController
,我将该数组用作数据源。
数据是从API正确输入的。 我可以将其添加到NSMutableArray
。 但是,似乎在MainTableViewController
,一旦到达以下行,就不再可以访问数组中的相同数据,并且一堆值都为null
:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
这是我正在使用的:
MainTableViewController.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.m
#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
StopCollection.h
#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.m
#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
StopItem.h
@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
这是我正在使用的JSON数据集:
{
"data":[
{
"station":"2 Av",
"lattitude":"40.723402",
"longitude":"-73.989938",
"stopTime":{
"data":[
{
"arrival_time":"02:40:30",
"trip":"JAMAICA - 179 ST",
"route":"some longer word with a -"
}
]
}
},
{
"station":"2 Av",
"lattitude":"40.723402",
"longitude":"-73.989938",
"stopTime":{
"data":[
{
"arrival_time":"00:54:00",
"trip":"CONEY ISLAND - STILLWELL AV",
"route":"some longer word with a -"
}
]
}
},
{
"station":"Delancey St",
"lattitude":"40.718611",
"longitude":"-73.988114",
"stopTime":{
"data":[
{
"arrival_time":"02:39:00",
"trip":"JAMAICA - 179 ST",
"route":"some longer word with a -"
}
]
}
},
{
"station":"Delancey St",
"lattitude":"40.718611",
"longitude":"-73.988114",
"stopTime":{
"data":[
{
"arrival_time":"00:55:30",
"trip":"CONEY ISLAND - STILLWELL AV",
"route":"some longer word with a -"
}
]
}
},
{
"station":"Essex St",
"lattitude":"40.718315",
"longitude":"-73.987437",
"stopTime":{
"data":[
{
"arrival_time":"01:23:30",
"trip":"JAMAICA CENTER - PARSONS/ARCHER",
"route":"some longer word with a -"
}
]
}
},
{
"station":"Essex St",
"lattitude":"40.718315",
"longitude":"-73.987437",
"stopTime":{
"data":[
{
"arrival_time":"00:52:30",
"trip":"BROAD ST",
"route":"some longer word with a -"
}
]
}
},
{
"station":"Bowery",
"lattitude":"40.72028",
"longitude":"-73.993915",
"stopTime":{
"data":[
{
"arrival_time":"01:22:00",
"trip":"JAMAICA CENTER - PARSONS/ARCHER",
"route":"some longer word with a -"
}
]
}
},
{
"station":"Bowery",
"lattitude":"40.72028",
"longitude":"-73.993915",
"stopTime":{
"data":[
{
"arrival_time":"00:54:00",
"trip":"BROAD ST",
"route":"some longer word with a -"
}
]
}
}
]
}
那与dispatch
无关。 这是因为您的属性weak
,会在可能的情况下(即在没有引用保留它们的情况下)将其清除。 从weak
变为strong
或在您的StopItem
模型中copy
,一切都会正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.