2013-05-06 2 views
0

Я сейчас застрял с этой ошибкой «EXC_BAD_ACCESS», и я не могу найти, что не так. Надеюсь, некоторые из вас найдут его.Управление памятью с помощью GCD, NSMutableArray и UITableView

Я загружаю файл, содержащий json-данные, сохраняю его как пользовательский NSObject в NSMutableArray, а затем представляю его в UITableView. Когда я собираюсь представить его в UITableView, я столкнулся с проблемами.

ViewController.h

@property (nonatomic, retain) NSMutableArray *menuItems; 

ViewController.m

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    menuItems = [[NSMutableArray alloc] init]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [self downloadMenu]; 

} 

-(void)downloadMenu 
{ 
    dispatch_queue_t fetchfromServerQueue = dispatch_queue_create("fetchfromServer", NULL); 

    [self createProgressionAlertWithMessage:@"Fetching menu"]; 

    dispatch_async(fetchfromServerQueue, ^{ 

     NSURL *menuURL = [NSURL URLWithString:@"anURL"]; 

     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:menuURL]; 

     NSError *error = nil; 
     NSURLResponse *response; 
     NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

     responseArray = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 

     menuItems = [[NSMutableArray alloc] initWithCapacity:[responseArray count]]; 

     for (int i = 0; i<[responseArray count]; i++) { 
      NSDictionary *menuObject = [responseArray objectAtIndex:i]; 

      NSString *x = [NSString stringWithFormat:@"%@", [menuObject objectForKey:@"x"]]; 
      NSString *y = [NSString stringWithFormat:@"%@", [menuObject objectForKey:@"y"]]; 
      NSString *z = [NSString stringWithFormat:@"%@", [menuObject objectForKey:@"z"]]; 

      MenuItem *menuItem = [[MenuItem alloc] initWithX:x andY:y andZ:z]; 

      [menuItems addObject:menuItem]; 

      [menuItem release]; 
     } 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      [progressAlert dismissWithClickedButtonIndex:0 animated:YES]; 
      [menuTable reloadData]; 
     }); 
    }); 
    dispatch_release(fetchfromServerQueue); 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [menuItems count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    } 

    MenuItem *menuItem = (MenuItem *)[menuItems objectAtIndex:indexPath.row]; 

    cell.textLabel.text = [NSString stringWithFormat:@"%@", [menuItem x]]; 

    return cell; 
} 

На "cell.textLabel.text = [NSString stringWithFormat: @" % @ "[MENUITEM х]];" Я получаю «EXC_BAD_ACCESS (код = 1, адрес = 0xXXXXXXXX)».

Я не использую ARC и не могу преобразовать его в ближайшем будущем с помощью этого проекта. Это создает проблему из-за недостатка знаний в управлении памятью.

Любая идея о том, что не так?

Thx!

#### #### #### #### #### #### #### #### ####

Это как MenuItem выглядит следующим образом:

#import <Foundation/Foundation.h> 

@interface MenuItem : NSObject 
{ 
    NSString *x; 
    NSString *y; 
    NSString *z; 
} 

-(id)initWithX:(NSString *)x_ andY:(NSString *)y_ andZ:(NSString *)z_; 
-(NSString *)x; 
-(NSString *)y; 
-(NSString *)z; 

@property(retain, nonatomic) NSString *x; 
@property(retain, nonatomic) NSString *y; 
@property(retain, nonatomic) NSString *z; 

@end 

#import "MenuItem.h" 

@implementation MenuItem 

@synthesize x; 
@synthesize y; 
@synthesize z; 

-(id)initWithX:(NSString *)x_ andY:(NSString *)y_ andZ:(NSString *)z_ 
{ 
    self = [super init]; 
    if(self) 
    { 
     x = x_; 
     y = y_; 
     z = z_; 
    } 

    return self; 
} 

-(void)dealloc 
{ 
    [x release]; 
    [y release]; 
    [z release]; 
    [super dealloc]; 
} 

-(NSString *)x 
{ 
return x; 
} 

-(NSString *)y 
{ 
    return y; 
} 

-(NSString *)z 
{ 
    return z; 
} 

@end 

ответ

1

Я не вижу ничего очевидного, возможно, что-то в menuItem вызывает проблему? Что делает [menuItem x]?

В общем, запустите приложение с помощью инструмента для зомби: cmd-i, затем выберите Zombies. Это даст вам трассировку распределений/выпусков объекта, который бросает EXC_BAD_ACCESS.

Удачи.

+0

Мое дикое предположение: ваш первый абзац - пятно, но второе немного. Я делаю ставку на то, что 'x', это не объект. – Chuck

+0

Я добавил код для MenuItem. 'x' - NSString. Вы видите проблемы с этим классом? – Cayak

+0

Я сегодня попробую Зомби. – Cayak

0

Это немного странно:

-(void)downloadMenu 
{ 
    dispatch_queue_t fetchfromServerQueue = dispatch_queue_create("fetchfromServer", NULL); 
    dispatch_async(fetchfromServerQueue, ^{ 
     ... 
    }); 
    dispatch_release(fetchfromServerQueue); 
} 

создавать очереди и дать ему асинхронной задачу сделать. Пока эта задача уходит, чтобы выполнить некоторую работу, вы сразу же освободите очередь. Это может вызвать несколько проблем, если задача async не завершится до ее выпуска.

Возможно, вы захотите остановиться на освобождении до тех пор, пока работа по асинхронному вызову не будет завершена.

+2

Это не проблема; блок сохраняет очередь до ее окончания. См. «Обсуждение» в [docs для 'dispatch_queue_create()'] (http://developer.apple.com/library/mac/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/doc/ uid/TP40008079-CH2-SW14) –

+0

Достаточно честный. Я смотрел на пример [oq] (http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html), где они размещают выпуск в обратном направлении. – Anonymous