到达numberOfRowsInSection和cellForRowAtIndexPath时,NSMutableArray为空

时间:2014-06-22 15:49:11

标签: ios objective-c arrays tableview

我正在尝试非常标准的操作,基本上,从我的本地SQLITE数据库获取所有记录,然后从Web获取其他数据,合并此数据(NSMutableArray)并在表视图中显示它。在viewDidLoad中,数组包含所有必需元素,但在numberOfRowsInSection:中,它等于nil。因此,我无法在tableview中显示项目。那么哪里可以设置为零?感谢您的任何帮助。 InboxViewControler.m的代码

//
//  ArticleViewController.m
//  ReadLater
//
//  Created by Ibragim Gapuraev on 09/06/2014.
//  Copyright (c) 2014 Sermilion. All rights reserved.
//

#import "InboxViewController.h"
#import "LoginViewController.h"
#import "SHCTableViewCell.h"

@interface InboxViewController ()

@end

@implementation InboxViewController

@synthesize db, articles, response, jsonData;



- (NSMutableArray* ) articles
{
    if (!articles) {
        articles = [[NSMutableArray alloc] initWithCapacity:20];
    }

    return articles;
}

- (Database* ) db
{
    if (!db) {
        db = [[Database alloc] init];
    }
    return db;
}


//---------------------------------Getting data from web-------------------------------------------//

/**
 The method will connect to a given url and send date of article that has been added at last.
 Then, connectionDidFinishLoading will receive json array of all articles, that have been added to server database after that time
 **/
#pragma mark Connection to server
- (void) makeConnetion:(id)data
{
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost/nextril/index.php"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];

    NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    //send id of article that was added last, to server,
    //which will return json arrya of all articles with id greater then the one sent
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];

    if (connection) {
        NSLog(@"viewWillAppear: Connecting to server to get data...");
    }else{
        NSLog(@"viewWillAppear: Error while connecting...");
    }


}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data
{
    response = [[NSData alloc] initWithData:data];
}

//Check if data been received
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    if(sizeof(response)>0){
        //NSLog(@"Got response from server %@", response);
        NSError* error;
        NSArray* json = [NSJSONSerialization
                              JSONObjectWithData:response //1
                              options:kNilOptions
                              error:&error];

        self.jsonData = [[NSMutableArray alloc] initWithArray:json];
        int count = 0;
        [self.db openDatabase];
        BOOL added = false;
        BOOL addedToUser = false;
        NSLog(@"jsonData %d", jsonData.count);
        for (int i=0; i<self.jsonData.count; i++) {

            NSDictionary *item = [self.jsonData objectAtIndex:i];
            NSString* content = [item objectForKey:@"content"];
            NSString* author = [item objectForKey:@"author"];
            NSString* date = [item objectForKey:@"date"];

            NSString* url = [item objectForKey:@"url"];
            NSString* tags = [item objectForKey:@"tags"];
            NSInteger archived = [[item objectForKey:@"archived"]integerValue];
            NSString* title = [item objectForKey:@"title"];
            //NSLog(@"",);

            Article* article = [[Article alloc]initWithId:0 content:content author:author date:date url:url tags:tags arhived:archived title:title];
            added = [self.db addArticleToArticleDB:article];

            if (added == true) {
                NSInteger last_id = [self.db getLastArticleID];
                article.article_id = last_id;
                [self.articles addObject:article];
                addedToUser = [self.db addArticleToUserArticleDB:article];
            }
            count++;
        }
        if (added == true && addedToUser == true) {

            NSLog(@"connectionDidFinishLoading: Articles has been imported. Size: %d %lu", jsonData.count, (unsigned long)jsonData.count);
        }else{
            NSLog(@"connectionDidFinishLoading: Failed to import article.");
        }
        NSArray *importedArticles =  [self.db importAllArticlesForUser:16 archived:0];
        [self.articles addObjectsFromArray:importedArticles];
        [self.db closeDatabase];
    }else{
        NSLog(@"connectionDidFinishLoading: Did not get resopnse from server: %@", response);
    }
    connection = nil;
}
//----------------------------------------------------------------------------------------------------
#pragma mark TODO: work out why data from server loads only after second login
#pragma mark view
- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];


    [self.db openDatabase];
    NSString* date_added = [self.db getLastArticleDate];
    [self makeConnetion:(id)date_added];
    NSLog(@"viewWillAppear: self.articles: %d", self.articles.count);
    [self.db closeDatabase];



}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    self.tableView.separatorColor = [UIColor clearColor];
    self.tableView.backgroundColor = [UIColor blackColor];
    [self.tableView registerClass:[SHCTableViewCell class] forCellReuseIdentifier:@"Content"];

}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    NSLog(@"numberOfRowsInSection: self.articles: %d", self.articles.count);
    return self.articles.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"Content";
    SHCTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.textLabel.backgroundColor = [UIColor clearColor];
    NSMutableArray* safeArticles = self.articles;
    // Configure the cell...
    Article* article = [safeArticles objectAtIndex:indexPath.row];
    NSString *listingKey = article.title;
    NSString *listingValues = article.url;
    cell.textLabel.text = listingKey;
    cell.detailTextLabel.text = listingValues ;
    cell.delegate = self;
    cell.todoItem = article;
    return cell;
}


#pragma mark cell atributes
-(UIColor*)colorForIndex:(NSInteger) index {
    NSUInteger itemCount = self.articles.count - 1;
    float val = ((float)index / (float)itemCount) * 0.6;
    return [UIColor colorWithRed: 1.0 green:val blue: 0.0 alpha:1.0];
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 70.0f;
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [self colorForIndex:indexPath.row];
}

#pragma mark TODO delete from server database
//method to delete an article form view and to call method to delete from database, as well as form server database
-(void)deleteArticle:(Article*)articleToDelete {
    . . . 
}

#pragma mark TODO delete from server database
//method to delete an article form view and to call method to delete from database, as well as form server database
-(void)archiveArticle:(Article*)articleToArchive {
    . . .
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

2 个答案:

答案 0 :(得分:0)

接受@akashg的建议并添加[self.tableView reloadData];获取数据后它奏效了。虽然,我不知道为什么会发生这种情况的机制。至少它是有效的)欢迎任何人添加他们的解释。谢谢。

答案 1 :(得分:0)

tableView调用datasource方法在viewDidLoad之后填充自己。如果此时数据源(通常是数组)为空,则tableView中不会显示任何内容。这就是为什么在数据源出现后必须调用reloadData的原因。在异步提取数据源的情况下尤其需要这样做。

根据Apple的documentation关于reloadData

  

调用此方法重新加载用于构造的所有数据   表,包括单元格,节头和页脚,索引数组和   等等。为了提高效率,表视图仅重新显示那些行   是可见的。如果表因此而缩小,它会调整偏移量   重装。表视图的委托或数据源调用此方法   何时希望表视图完全重载其数据的方法。它   不应该在插入或删除行的方法中调用,   特别是在通过调用实现的动画块中   beginUpdates和endUpdates