无法在IOS7中重新加载表视图

时间:2013-12-17 00:13:41

标签: ios uitableview

我是IOS开发的新手,并且一直在与它斗争。我想显示用户从我的服务器获得的电话列表,但tableview不显示项目。我从服务器获得的数据很好,我认为UItableView的设置是正确的。这是我的代码:

STKPhoneHolderViewController.h

#import <UIKit/UIKit.h>
#import "STKSimpleHttpClientDelegate.h"

@interface STKPhoneHolderViewController : UITableViewController <UITableViewDataSource, STKSimpleHttpClientDelegate>
@property (strong, nonatomic) IBOutlet UITableView *phoneTable;
@property (strong, nonatomic) NSMutableArray *phoneArray;

@end

STKPhoneHolderViewController.m

@implementation STKPhoneHolderViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    self.phoneTable.dataSource = self;
    self.phoneArray = [[NSMutableArray alloc]init];

    [self loadPhoneList];

}


#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    return [self.phoneArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"PhoneCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

        STKPhoneHolder *phoneHolder = [self.phoneArray objectAtIndex:indexPath.row];
        [cell.textLabel setText:phoneHolder.userName];


    return cell;
}

#pragma Custom method
- (void) loadPhoneList
{

    self.phoneArray = [[NSMutableArray alloc]init];

    STKSimpleHttpClient *client = [[STKSimpleHttpClient alloc]init];
    client.delegate = self;

    NSString *userId = @"your_id_h";

    NSString *sUrl = [NSString stringWithFormat:@"%@%@?userid=%@",
                      MOBILE_API_URL,
                      PHONEHOLDER_URI,
                      userId];

    [client send:sUrl data:@""];
}

#pragma STKSimpleHttpClientDelegate
-(void) complete:(STKHttpResult*) result
{
     if (result.ok != YES){
         [STKUtility alert:result.message];
         return;
     }

    self.phoneArray = (NSMutableArray*)result.result;
    for (STKPhoneHolder *holder in self.phoneArray) {
        NSLog(@"%@", [holder description]);
    }

    [self.phoneTable reloadData];
    NSLog(@" isMainThread(%d)", [NSThread isMainThread] );
}


@end

STKSimpleHttpClient.m

#import "STKSimpleHttpClient.h"
#import "STKSimpleHttpClientDelegate.h"

@implementation STKSimpleHttpClient

NSMutableData *responseData;
STKHttpResult *httpResult;


void (^completeFunction)(STKHttpResult *);

- (void) send:(NSString*)url
         data:(NSString*)data
{
    httpResult = [[STKHttpResult alloc]init];
    dispatch_async(dispatch_get_main_queue(), ^{

        if ( data == nil) return;

        //Get request object and set properties
        NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: url]];
        //set header for JSON request and response
        [urlRequest setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
        [urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
        //set http method to POST
        [urlRequest setHTTPMethod:@"POST"];
        //set time out
        [urlRequest setTimeoutInterval:20];

        NSData *body = [data dataUsingEncoding:NSUTF8StringEncoding];
        //set request body
        urlRequest.HTTPBody = body;

        //connect to server
        NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
        if (conn==nil){
            //Do something
        }
    });
}

#pragma mark - NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    // A response has been received, this is where we initialize the instance var you created
    // so that we can append data to it in the didReceiveData method
    // Furthermore, this method is called each time there is a redirect so reinitializing it
    // also serves to clear it
    responseData = [[NSMutableData alloc] init];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the new data to the instance variable you declared
    [responseData appendData:data];
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {
    // Return nil to indicate not necessary to store a cached response for this connection
    return nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // The request is complete and data has been received
    // You can parse the stuff in your instance variable noow
    NSError *error;
    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

    BOOL ok = [[json objectForKey:@"ok"] boolValue];
    NSString *message = [json objectForKey:@"message"];
    if (ok == NO) {
        [httpResult setError:message];
    } else {
        [httpResult setSuccess:[json objectForKey:@"result"]];
    }

    if (self.delegate !=nil) {
        [self.delegate complete:httpResult];
    }

    responseData = nil;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    // The request has failed for some reason!
    // Check the error var
    if (self.delegate !=nil) {
        [self.delegate complete:[httpResult setError:@"Connection failed."]];
    }
}

STKPhoneHolder.m

#import <Foundation/Foundation.h>

@interface STKPhoneHolder : NSObject

@property NSString *deviceId;
@property NSString *userId;
@property NSString *userName;
@property NSString *msn;

- (id) initWithDeviceId:(NSString*)aDeviceId
                 userId:(NSString*)aUserId
            userName:(NSString*)aUserName
            msn:(NSString*)aMsn;

@end

日志:

2013-12-17 16:14:23.447 [5323:70b] {
    deviceId = 11111;
    email = "";
    msn = 11111111;
    role = "";
    userId = aaaaaa;
    userName = "Joshua Pak";
}
2013-12-17 16:14:23.448 [5323:70b] {
    deviceId = 22222;
    email = "";
    msn = 2222222;
    role = "";
    userId = bbbbb;
    userName = "Jasdf Pak";
}
2013-12-17 16:14:23.449 Stalker[5323:70b]  isMainThread(1)

我可以在“完整”方法中看到日志打印phoneArray和两部手机,但tableview只显示“No record”。即使我调用reloadData方法,Tableview也不会再次渲染。我确保在调试模式下调用[self.phoneTable reloadData]。 我还需要做些什么?

4 个答案:

答案 0 :(得分:3)

尝试在主线程中调用reloadData

#pragma STKSimpleHttpClientDelegate
-(void) complete:(STKHttpResult*) result
{
     if (result.ok != YES){
         [STKUtility alert:result.message];
         return;
     }

    self.phoneArray = (NSMutableArray*)result.result;

    for (STKPhoneHolder *holder in self.phoneArray) {
            NSLog(@"%@", [holder description]);
        }

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

或者您可以使用performSelectorOnMainThread

[self.phoneTable performSelectorOnMainThread:@selector(reloadData)
                                 withObject:nil
                              waitUntilDone:NO];

我猜测STKSimpleHttpClient类在不同的线程上调用完整的委托函数,所有用户界面交互都假设从主线程调用。

尝试使用此代码查看完整委托函数中的哪个主题

NSLog(@" isMainThread(%d)", [NSThread isMainThread] );

答案 1 :(得分:0)

检查一下。在从Web服务获取信息之前,代码是否加载了tableview。如果是,那么写下声明[tableview Reload];在Web服务信息获取过程旁边。这将有助于

答案 2 :(得分:-1)

没有必要指定部分的数量,但您可能希望使用此代码执行此操作:

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

答案 3 :(得分:-1)

我看到你正在使用Table View Controller,它已经有一个tableView引用self.tableView

就像@rdelmar所说,你可以使用那个引用代替你的phoneTable:

[[self tableView] setDataSource:self];
[[self tableView] setDelegate:self];
[[self tableView] reloadData];