我是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]。 我还需要做些什么?
答案 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];