为啥 UITableView 不从数组中填充

Posted

技术标签:

【中文标题】为啥 UITableView 不从数组中填充【英文标题】:Why Isn't UITableView Populating From Array为什么 UITableView 不从数组中填充 【发布时间】:2013-03-06 15:15:45 【问题描述】:

我是 iphone 开发的菜鸟(xcode 中的第 3 天),我无法从 NSMutableArray 填充表格视图。我使用this 教程作为我的指南,我的实现稍作修改,因此我可以在pageControl 中显示表格。我确定我的数组正在填充数据,但填充数组后它不会显示在表中。我尝试使用重新加载数据方法,但这会导致我的应用程序崩溃。任何帮助是极大的赞赏。

我的代码

标题

#import <UIKit/UIKit.h>

@interface TwitterView : UIViewController <UITableViewDelegate>

NSMutableArray *tweets;  
UITableView *twitterTable;    

 

@property (nonatomic, retain) NSMutableArray *tweets;  
@property (nonatomic, retain) IBOutlet UITableView *twitterTable;
@end

实施

#import "TwitterView.h"
#import "Tweet.h"


//JSON 
@interface NSDictionary(JSONCategories)
+(NSDictionary*)dictionaryWithContentsOfJSONURLString:(NSString*)urlAddress;
-(NSData*)toJSON;
@end

@implementation NSDictionary(JSONCategories)
+(NSDictionary*)dictionaryWithContentsOfJSONURLString:(NSString*)urlAddress

    NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString: urlAddress] ];
__autoreleasing NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions     error:&error];
if (error != nil) return nil;
return result;


-(NSData*)toJSON

NSError* error = nil;
id result = [NSJSONSerialization dataWithJSONObject:self options:kNilOptions error:&error];
if (error != nil) return nil;
return result;    

@end

@implementation TwitterView

@synthesize tweets;
@synthesize twitterTable;

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad 
  [super viewDidLoad];

tweets = [[NSMutableArray alloc]init];
//JSON CODE
dispatch_async(kBgQueue, ^
    NSData* data = [NSData dataWithContentsOfURL: twitterURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];
);



#pragma mark -
#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.
return [tweets count];


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

return 80;



// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];


  // Configure the cell...

NSDictionary *aTweet = [tweets objectAtIndex:[indexPath row]];

    cell.textLabel.text = [aTweet objectForKey:@"text"];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.textLabel.font = [UIFont systemFontOfSize:12];
cell.textLabel.minimumFontSize = 10;
cell.textLabel.numberOfLines = 4;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;

cell.detailTextLabel.text = [aTweet objectForKey:@"from_user"];

NSURL *url = [NSURL URLWithString:[aTweet objectForKey:@"profile_image_url"]];
NSData *data = [NSData dataWithContentsOfURL:url];
cell.imageView.image = [UIImage imageWithData:data];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
 

#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
 // Navigation logic may go here. Create and push another view controller.
/*
 <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc]   initWithNibName:@"<#Nib name#>" bundle:nil];
 // ...
 // Pass the selected object to the new view controller.
 [self.navigationController pushViewController:detailViewController animated:YES];
 [detailViewController release];
 */



#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning 
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Relinquish ownership any cached data, images, etc that aren't in use.


- (void)dealloc 
[tweets release];
[twitterTable release];
[super dealloc];



//JSON CODE
- (void)fetchedData:(NSData *)responseData 
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData //1
                                                     options:kNilOptions 
                                                       error:&error];


tweets = [json objectForKey:@"results"];
NSLog(@"The Tweets %@", tweets);    

//[twitterTable reloadData];<--Cause app to crash




@end

【问题讨论】:

能否检查一下是否连接了tableView的IBOutlets及其DataSource和Delegate? 【参考方案1】:
tweets = [json objectForKey:@"results"];

在这里,您将 autoreleased 值设置为 tweets ivar,当您尝试将其用于表视图时,它会被释放。要解决此问题,请不要为您的实例变量赋值,而是使用属性(它还可以防止之前存储在 tweets 变量中的值泄漏):

self.tweets = [json objectForKey:@"results"];

还可以考虑使用 ARC(自动引用计数),它将帮助您避免很多内存管理问题。

【讨论】:

哇!那行得通。太感谢了。这让我困惑了一个小时。这么简单的事情让我非常伤心。 Obj-c 内存管理是大量错误的来源,因此我再次强烈建议您在项目中尽可能使用 ARC

以上是关于为啥 UITableView 不从数组中填充的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Room 不从资产中填充数据库?

用部分动态填充分组的 uitableView

关闭模式视图时如何在 UITableView 中显示数据

UITableView 在 TableView 中间加载单元格。为啥?

为啥我的 UITableView 不显示数据?

为啥我的 plist 不会填充我的 UITableView?