views:

95

answers:

3

Hi!

I try to get the data of an array in an TableView but get an bad access error all the time. My code looks like this:

NewsViewController.h

#import "StatusMessage.h"

@interface NewsViewController : UIViewController {
    IBOutlet UITableView *table;
    NSMutableArray *statusMessages; 
}

@property(nonatomic, retain) NSMutableArray *statusMessages;

@end

NewsViewController.m

#import "NewsViewController.h"
#import "TBXML.h"

@implementation NewsViewController

@synthesize statusMessages;

-(void) getXML {
    //some XML things parsing above

        for (int i = 0; i smaller [allMessages count]; i++) {
        statusMessage *temp = [[StatusMessage alloc]init];

        NSLog(@"retain count %d", [statusMessages retainCount]); //is 1
        [temp initstatusMessage: str1:str2:str3:str4];

        [statusMessages addObject: temp];
        NSLog(@"retain count %d", [statusMessages retainCount]); // is 1
        [temp release];
    }   
}

-(void) getLda {    
    self.getXML;
    NSLog(@"retain count %d", [statusMessages retainCount]); // is 1

    NSComparisonResult dateSort(StatusMessage *d1, StatusMessage *d2, void *context) {
        return [[d2 getDate] compare:[d1 getDate]];
    }       

    [statusMessages sortUsingFunction:dateSort context:nil];
}

- (void)loadView {
    [[self navigationController] setNavigationBarHidden:NO animated:NO];
    table.backgroundColor = [UIColor clearColor];   
    [super loadView];
}



- (void)viewDidLoad {   
    [super viewDidLoad];

    statusMessages = [[NSMutableArray alloc] initWithObjects:nil];  
    NSLog(@"retain count %d", [statusMessages retainCount]); // is 1    

    self.getLda;
    NSLog([[statusMessages objectAtIndex:1] getText]); //works fine for every index
}

- (void)dealloc {
    [statusMessages release];   
    [super dealloc];    
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [statusMessages count];
}


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


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"retain count %d", [statusMessages retainCount]); // is 1 every time

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = [[statusMessages objectAtIndex:indexPath.section] getText];
    cell.textLabel.font = [UIFont systemFontOfSize:15];

    return cell;    
}

NewsMessage.h

#import 


@interface statusMessage : NSObject {
    NSString *source;
    NSString *text;
    NSString *date;
    NSURL    *link; 
}

-(void) initstatusMessage: (NSString *) s: (NSString *) t: (NSString *) l:(NSString *) d;
-(NSString *) getText;
-(NSDate   *) getDate;

@end

NewsMessage.m

#import "statusMessage.h"


@implementation statusMessage

-(void) initstatusMessage: (NSString *) s: (NSString *) t: (NSString *) l:(NSString *) d {
    source = s;
    link   = [[NSURL alloc] initWithString:l];

    text = t;

    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
    [formatter setDateFormat:@"yyyy-MM-ddeHH:mm:ssZZZZ"];
    date = [formatter dateFromString: d]; 
}

-(NSString *) getText {
    return (NSString *) CFURLCreateStringByReplacingPercentEscapesUsingEncoding (kCFAllocatorDefault , text, CFSTR(""), kCFStringEncodingUTF8);
}

-(NSDate *) getDate {
    return date;
}

@end

I just can't access the data in the cellForRowAtIndexPath-Method. Would be great if someone can help me.

+1  A: 

hi, setting up a tableview is not just the method 'cellForRowAtIndexPath'. there are some other methods you have to implement. e.g.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

and some more. it depends also on what you want your tableview is able to. you should make a tableview-tutorial or look in a tutorial project file where you find all the important things you have to do. (google for 'uitableview tutorial', there is so much out in the web...)

Micko
Ok, sry, i wasn't precise enough. The problem isn't the table. I think it's a memory management problem. It's the same problem if i try NSLog([[statusMessages objectAtIndex:indexPath.section] getText]); in the cellForRowAtIndexPath-Method. I get an “EXC_BAD_ACCESS”.
Grt
A: 

3. (and hopefully final) UPDATE:

When you pass an argument to a function, the argument does not get retained. Same thing is true for assigning variables. In other words:

source = s; text = t; date = [formatter dateFromString: d]; 

are not retained by your class (link... however is, since you use "alloc"). So, use

source = [s retain];
text = [t retain];
date = [[formatter dateFromString: d]retain];

and you should be fine. Don't forget to release them in your dealloc.

Please take a close look at the concept of memory management again. I don't want to be rude, but you obviously haven't fully picked it up yet.

Hope, we've got it now!

[Rest of the post deleted since most of it was guesswork.]

Phlibbo
I suspect the same thing.
tia
The "getLda" looks like this: { StatusMessage *temp = [[[StatusMessage alloc]init] retain]; [temp initstatusMessage: str1:str2:str3:str4]; [statusMessages addObject: temp];}That's everything.
Grt
And (of course) getLda is called more than one time, otherwise an array wont be very useful.
Grt
There is nothing in this method that would cause the crash. However, you should look at retain counts again. At the end *temp has a retain count of +3 (alloc, retain (which is unnecessary) and addObject), so you should get rid of the retain and release temp at the end of your method. To solve your inital problem, you might want to post the whole NewsViewController (not in a comment please :) ), there must be some place, where you accidentally release or overwrite the array.
Phlibbo
Or just look at my update. Since I don't have the complete code, this is another guess, but maybe I'm right this time.
Phlibbo
Hi, thank you for your help, i added the code in my question above.The retain count of "newsMessages" is 1 all the time.The thing i dont get is: After saving stuff in the array, i can access every element of the array in "viewDidLoad" without problems. So the problem happens somewhere between this line and the call of cellForRowAtIndexPath.
Grt
Please look at my new update, hope it helps.
Phlibbo
Thank you again!I added the code of NewsMessage."statusMessage" is right in my code "StatusMessage",sry for this. The init method was empty, so its now:StatusMessage *temp = [StatusMessage alloc];str1,str2.. was just to illustrate, the "real" call looks like this [temp initstatusMessage: @"Fb":[aMessage objectForKey:@"message"]:link:[aMessage objectForKey:@"created_time"]];aMessage is a Dictionary made by a JSON request.NSDictionary *results = [jsonString JSONValue]; NSArray *allMessages = [results objectForKey:@"data"]; NSDictionary *aMessage = [allMessages objectAtIndex:0];
Grt
Once again, look at my update please :)
Phlibbo
That's it! Thank you so much!!! And yes you're right, i know now i have to take a closer look at the memory management, usually i'm a java programmer and i simply underestimated the topic. Thank you for your patience!
Grt
A: 

You are also over-retaining your array, you do:

[[NSMutableArray alloc] initWithObjects:nil] retain];

when you really just need:

[[NSMutableArray alloc] initWithObjects:nil];

Since alloc/init leaves the retain count at one as well.

Kendall Helmstetter Gelner