UIPickerView EXC BAD ACCESS?

时光毁灭记忆、已成空白 提交于 2019-12-19 09:26:27

问题


I keep getting a exc bad access error and I think it has something to do with my UIPickerView because this is when the app crashes. Everything works fine until I make a 9th choice from the UIPickerView. Every single time the app crashes on the 9th choice. Any ideas?

- (void)viewDidLoad {
        [super viewDidLoad];



     list = [[NSMutableArray alloc] init];
     [list addObject:@"Anvil"];
     [list addObject:@"Apple"];
     [list addObject:@"Arrow"];
     [list addObject:@"Baby"];
     [list addObject:@"Basketball"];
     [list addObject:@"Beehive"];
     [list addObject:@"Blimp"];
     [list addObject:@"Bomb"];
     [list addObject:@"Bungee Jumper"];
     [list addObject:@"Cactus"];
     [list addObject:@"Cake"];
     [list addObject:@"Car"];
     [list addObject:@"Caterpillar"];
     [list addObject:@"Couch"];
     [list addObject:@"Dennis"];

        anvil = [UIImage imageNamed:@"anvil.png"];
     apple = [UIImage imageNamed:@"apple.png"];
     arrow = [UIImage imageNamed:@"arrow.png"];
     baby = [UIImage imageNamed:@"baby.png"];
     basketball = [UIImage imageNamed:@"basketball.png"];
     beehive = [UIImage imageNamed:@"beehive.png"];
     blimp = [UIImage imageNamed:@"blimp.png"];
     bomb = [UIImage imageNamed:@"bomb.png"];
     bungeejumper = [UIImage imageNamed:@"bungeejumper.png"];
     cactus = [UIImage imageNamed:@"cactus.png"];
     cake = [UIImage imageNamed:@"cake.png"];
     car = [UIImage imageNamed:@"car.png"];
     caterpillar = [UIImage imageNamed:@"caterpillar.png"];
     couch = [UIImage imageNamed:@"couch.png"];
     dennis = [UIImage imageNamed:@"dennis.png"];
    }

    -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView{
     return 1;
    }

    -(NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component{

     return [list count];
    }

    -(NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{

     return [list objectAtIndex:row];
    }

    - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {

     if([[list objectAtIndex:row] isEqual:@"Anvil"]) {
      [object setImage:anvil];
     }
     else if([[list objectAtIndex:row] isEqual:@"Apple"]) {
      [object setImage:apple];
     }
     else if([[list objectAtIndex:row] isEqual:@"Arrow"]) {
      [object setImage:arrow];
     }
     else if([[list objectAtIndex:row] isEqual:@"Baby"]) {
      [object setImage:baby];
     }
     else if([[list objectAtIndex:row] isEqual:@"Basketball"]) {
      [object setImage:basketball];
     }
     else if([[list objectAtIndex:row] isEqual:@"Beehive"]) {
      [object setImage:beehive];
     }
     else if([[list objectAtIndex:row] isEqual:@"Blimp"]) {
      [object setImage:blimp];
     }
     else if([[list objectAtIndex:row] isEqual:@"Bomb"]) {
      [object setImage:bomb];
     }
     else if([[list objectAtIndex:row] isEqual:@"Bungee Jumper"]) {
      [object setImage:bungeejumper];
     }
     else if([[list objectAtIndex:row] isEqual:@"Cactus"]) {
      [object setImage:cactus];
     }
     else if([[list objectAtIndex:row] isEqual:@"Cake"]) {
      [object setImage:cake];
     }
     else if([[list objectAtIndex:row] isEqual:@"Car"]) {
      [object setImage:car];
     }
     else if([[list objectAtIndex:row] isEqual:@"Caterpillar"]) {
      [object setImage:caterpillar];
     }
     else if([[list objectAtIndex:row] isEqual:@"Couch"]) {
      [object setImage:couch];
     }
     else if([[list objectAtIndex:row] isEqual:@"Dennis"]) {
      [object setImage:dennis];
     }
    }

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

回答1:


You're not retaining your UIImages so they're being autoreleased. After every imageNamed call, you need a retain i.e.

baby = [[UIImage imageNamed:@"baby.png"] retain];

or, if you've declared them as properties (i.e. @property (nonatomic, retain) UIImage *baby;) you can do this :

self.baby = [UIImage imageNamed:@"baby.png"];

which is the more correct way to do it.


However, a better way of dealing with all this code might be to use an array of images instead of checking for the name each time. i.e.

imageArray = [NSArray alloc] initWithObjects:
              [UIImage imageNamed:@"Anvil.png"],
              [UIImage imageNamed:@"Apple.png"],
              [UIImage imageNamed:@"Arrow.png"],
              nil];

and then, when an item is selected,

- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    [object setImage:[imagearray objectAtIndex:row]];
 }

which is a little cleaner ;)

EDIT: Douglas has had the same idea for cleaning up the code while I was writing the second half of my answer :)




回答2:


Is the ninth object the only one with a space in the name? I don't see how that could break it, looking for differences between it and the others. The image isn't called "bungee jumper.png" instead of "bungeejumper.png" is it?

Aside: instead of a list of strings, you could have a list of image title pairs Eg,

// ... snip ...
[self addPairWithTitle:@"Anvil" image:@"anvil.png"];
[self addPairWithTitle:@"Apple" image:@"apple.png"];

- (void) addPairWithTitle .... 
{
    // you'll need to define a MyNewPair object which retains the image and title
    [list addObject:[[MyNewPair alloc] initWithTitle:title andImage:[UIImage imageNamed:imageName]];
}

// ... snip ...

... titleForRow...
return [[list objectAtIndex:row] title];

...didSelectRow...
[object setImage:[[list objectAtIndex:row]] image];


来源:https://stackoverflow.com/questions/2426651/uipickerview-exc-bad-access

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!