具有异步调用的空UITableViewController

时间:2018-10-22 06:32:30

标签: objective-c uitableview asynchronous

我正在使用NSURLSession和JSON序列化从我的网站中获取内容。异步调用和获取JSON数据可以完美地工作。我的问题是,当要在TableviewController中显示数据时,我放置了一个NSLog语句以查看是否有数据,但是cell.textlable.text从未更新。我猜这是线程的问题,但我无法弄清楚。你能帮忙吗?

@interface MainTableViewController : 
UITableViewController<LokalModelProtocol>


@property (strong,nonatomic) NSMutableArray* arr;

@end

@implementation MainTableViewController
 @synthesize arr;

- (void)viewDidLoad {
[super viewDidLoad];
arr = [[NSMutableArray alloc]init];
LokalModel *lokal = [[LokalModel alloc]init];
lokal.delegate=self;
[lokal downloadItems];

}

-(void)itemsDownloaded:(NSMutableArray *)items
{
arr=items;
//NSLog(@"%@", items);
[self.tableView reloadData];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Incomplete implementation, return the number of sections
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section {
#warning Incomplete implementation, return the number of rows
// return 1;

return [arr count];
}


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

PostModel *post = [[PostModel alloc]init];
post =[arr objectAtIndex:indexPath.row];


NSLog(@"%@", post.postTitle); ////this outputs the correct strings///////

cell.textLabel.text =[NSString stringWithFormat:@"%@", post.postTitle];
cell.detailTextLabel.text = post.postTitle;///neither of these do//////

return cell;
}

@end





@protocol LokalModelProtocol <NSObject,NSURLSessionDelegate>

+(void)itemsDownloaded:(NSMutableArray*)items;

@end

@interface LokalModel : NSObject

-(void)downloadItems;
@property (strong, nonatomic) NSMutableData* thedata;
@property (strong, nonatomic) NSString* urlString;
@property (strong, nonatomic) NSURL* theUrl;
@property (strong,nonatomic) id<LokalModelProtocol>delegate;
+(void)parseJson:(NSData*)data;

@end





id<LokalModelProtocol>delegate;

@implementation LokalModel;
@synthesize thedata,urlString,theUrl,delegate;

-(void)downloadItems{
NSURL *theUrl = nil;
static NSString* urlString = @"https://balalatet.com/wp-json/wp/v2/posts";
theUrl=[NSURL URLWithString:urlString];

NSURLSession *currentSession= [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDataTask *task = [currentSession dataTaskWithURL:theUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error){
        [NSException raise:@"error" format:@"%@",error.localizedDescription];
        NSLog(@"error1");
    }
    else{
        NSLog(@"success");
        [LokalModel parseJson:data];

    }


}];
[task resume];

}

+(void)parseJson:(NSData*)data{

NSArray *jsonResults = [[NSArray alloc]init];
NSError *jsonerror;
jsonResults =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonerror];

if (jsonerror)
    [NSException raise:@"json error" format:@"%@",jsonerror.localizedDescription];

NSMutableArray *posts = [[NSMutableArray alloc] init];
NSMutableDictionary *jsonElenent =[NSMutableDictionary dictionary];

for (NSMutableDictionary *d in jsonResults)
{
    jsonElenent=d;
    PostModel *thePost=[[PostModel alloc]init];
    thePost.postId= jsonElenent[@"id"];
    thePost.postDate= jsonElenent[@"date"];
    thePost.postDategmt= jsonElenent[@"date_gmt"];
    thePost.postGuid= jsonElenent[@"guid"];
    thePost.postSlug= jsonElenent[@"slug"];
    thePost.postStatus= jsonElenent[@"status"];
    thePost.postSticky= jsonElenent[@"sticky"];
    thePost.postPingStatus= jsonElenent[@"ping_status"];
    thePost.postType= jsonElenent[@"type"];
    thePost.postCommentStatus= jsonElenent[@"comment_status"];
    thePost.postTags= jsonElenent[@"tags"];
    thePost.postTitle= jsonElenent[@"title"];
    thePost.postTemplate= jsonElenent[@"template"];
    thePost.postLink= jsonElenent[@"link"];
    thePost.postMeta= jsonElenent[@"meta"];
    thePost.postModified= jsonElenent[@"modified"];
    thePost.postModifiedgmt= jsonElenent[@"modified_gmt"];
    thePost.postFeaturedMedia= jsonElenent[@"featured_media"];
    thePost.postFormat= jsonElenent[@"format"];
    thePost.postLinks= jsonElenent[@"links"];
    thePost.postAuthor= jsonElenent[@"author"];
    thePost.postContent= jsonElenent[@"content"];
    thePost.postCategory= jsonElenent[@"category"];
    thePost.postExcerpt= jsonElenent[@"excerpt"];
    NSLog(@"%@", thePost.postTitle);
    [posts addObject:thePost];
}
dispatch_async(dispatch_get_main_queue(), ^{
    [delegate itemsDownloaded:posts];
});
}
@end

更新

我的道歉作为我的调试信息的一部分是不正确的。 nslog输出不是来自cellForRowAtIndexPath方法。实际上,arr数组仍然为空,因为     (void)个项目下载:(NSMutableArray *)个项目 从未被调用。我确定我正确设置了协议。为什么MainTableViewControllerClass无法获取数据有什么想法?

更新

所以我意识到我忘了删除线

id<LokalModelProtocol>delegate;
我在LokalModel中的@implementation之前放置的

。但现在这样做会导致在行

处出现错误“无法识别的选择器发送到实例”
[delegate itemsDownloaded:posts];

我也尝试过

[self.delegate itemsDownloaded:posts];

但它会引发相同的异常。

已解决

我的协议方法必须是实例方法,而我将其设置为类方法。

2 个答案:

答案 0 :(得分:0)

在返回单元格之前,请尝试在cellForRowIndexPath中添加此代码

[需要的单元格布局];

答案 1 :(得分:0)

我相信您必须先使用registerNib:forCellReuseIdentifier:(例如,在viewDidLoad中)添加registerClass:forCellReuseIdentifier:dequeueReusableCellWithIdentifier:forIndexPath:

摘自文档:https://developer.apple.com/documentation/uikit/uitableview/1614878-dequeuereusablecellwithidentifie?language=objc

  

重要   调用此方法之前,必须使用registerNib:forCellReuseIdentifier:或registerClass:forCellReuseIdentifier:方法注册类或nib文件。