1

I'm a noob to iphone development (3rd day in xcode) and I'm having trouble populating a tableview from an NSMutableArray. I'm using this tutorial as my guide and my implementation of it is slightly modified so I can show the table within a pageControl. I'm sure my array is populating with data but after the array is populated it doesn't show in the table. I've tried using the reload data method but that cause my app to crash. Any help is greatly appreciated.

MY CODE

Header

#import <UIKit/UIKit.h>

@interface TwitterView : UIViewController <UITableViewDelegate>{

NSMutableArray *tweets;  
UITableView *twitterTable;    

} 

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

Implementation

#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
1
  • Can you check if you have connected IBOutlets of tableView and its DataSource and Delegate? Commented Mar 6, 2013 at 15:21

1 Answer 1

1
tweets = [json objectForKey:@"results"];

Here you set autoreleased value to tweets ivar and it gets deallocated by the time you try to use it for table view. To fix the issue do not assign value to your instance variable, use property instead (it will also prevent previous value stored in tweets variable to leak):

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

Also consider using ARC (automatic reference counting), it will help you to avoid a lot of memory management problems.

Sign up to request clarification or add additional context in comments.

2 Comments

Wow!!! That Worked. thank you so much. It had me baffled for an hour. Something so simple caused me so much grief.
Obj-c memory management is a source of tons of bugs, so once again I'd strongly advise to use ARC in your projects whenever possible

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.