Search code examples
iosuitableviewafnetworkingjsonkit

UITableView crashes when using JSON parsed data from AFnetworking


I am currently trying to parse data from a web service and format it inside of my UITableView.

Details about the project: Deployment Target: ios 4.3

jsonTapped function:

-(void) jsonTapped
{
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL   URLWithString:@"http://localhost"]];
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
                                                        path:@""
                    parameters:@{@"provider":@"12",
                                @"var":@"titles"}];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) 
{
    // Print the response body in text
    NSLog(@"Response: %@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
    NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    orderItems = [str objectFromJSONString];
    list = [orderItems objectAtIndex:0];
} 
failure:^(AFHTTPRequestOperation *operation, NSError *error) 
{
    NSLog(@"Error: %@", error);
}];
[operation start];
}

The data comes in as an array of dictionaries. I have checked with class checking function. List is a dictionary declared in the .h file, and orderItems is an NSArray declared in the .h file.

When I go to update my UITableView, things go terribly. If I attempt to access a piece of data in list (at anywhere outside of my jsonTapped funciton), the whole thing crashes.

How can I fix this? Any ideas on why the information I put in to the orderItems array is not being retained?

When it crashes, it just says (lldb) and then directs me to code with a green error saying "Thread 1: EXC_BAD_ACCESS ..."

Thanks!


Solution

  • I see that you're assigning an autoreleased object to your class variable. If you're using an ivar, you'll have to retain this information yourself. It's easier to use a property where you can declare it as retain. Here's how:

    In your .h

    @interface MyClass {
    
        NSArray *orderItems;
        NSDictionary *list;
    }
    
    @end
    

    Becomes:

    @interface MyClass
    
    @property (nonatomic, retain) NSArray *orderItems;
    @property (nonatomic, retain) NSDictionary *list;
    
    @end
    

    In your .m file, in your jsonTapped method:

    orderItems = [str objectFromJSONString];
    list = [orderItems objectAtIndex:0];
    

    becomes:

    self.orderItems = [str objectFromJSONString];
    self.list = [orderedItems objectAtIndex:0];
    

    You could also do this:

    orderItems = [[str objectFromJSONString] retain];
    list = [[orderItems objectAtIndex:0] retain];
    

    But then, you'll have to remember to release them somewhere otherwise you'll have a memory leak.

    For properties, it's as simple as setting them to nil. The compiler will know to release the object when necessary.

    Here's what your dealloc method should look like:

    - (void)dealloc {
    
        self.orderItems = nil;
        self.list = nil;
    
        ...
    
        [super dealloc];
    }