I find that randomly I get a EXC_BAD_ACCESS error on the iPhone when updating the status. This occurs pretty randomly.
Anyone have any idea to how this make be fixed?
#import 'TwitterViewController.h' NSString *_testUID = nil; NSString *sImageName; @implementation TwitterViewController //Turns NSLogs into comments //#define NSLog // - (void)viewDidLoad { self.title = @'Twitter'; arrayEmotes = [[NSMutableArray alloc] init]; [arrayEmotes addObject:@'Happy']; [arrayEmotes addObject:@'Sad']; [arrayEmotes addObject:@'Tongue']; [arrayEmotes addObject:@'Drunk']; [arrayEmotes addObject:@'Bored']; [arrayEmotes addObject:@'Love']; [arrayEmotes addObject:@'Sleepy']; [arrayEmotes addObject:@'Sick']; [arrayEmotes addObject:@'Awake']; [arrayEmotes addObject:@'Shocked']; [arrayEmotes addObject:@'Angry']; [arrayEmotes addObject:@'Laughing']; [arrayEmotes addObject:@'Dancing']; [arrayEmotes addObject:@'Confused']; [activityView startAnimating]; [currentActivity setText:@'Logging In']; NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:@'username_preference']; NSString *password = [[NSUserDefaults standardUserDefaults] stringForKey:@'password_preference']; // Make sure you entered your login details before running this code... ;) if ([username isEqualToString:@''] || [password isEqualToString:@'']) { //Show the UIAlert if no username or password is stored in the settings UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@'Error' message:@'Incorrect username/password stored in the settings.' delegate:self cancelButtonTitle:@'OK' otherButtonTitles:nil]; [alert show]; [alert release]; NSLog(@'You forgot to specify your username/password in settings.bundle!'); } // Create a TwitterEngine and set our login details. twitterEngine = [[[MGTwitterEngine alloc] initWithDelegate:self] retain]; [twitterEngine setUsername:username password:password]; // Get updates from people the authenticated user follows. //[twitterEngine getFollowedTimelineFor:username since:nil startingAtPage:0]; _testUID = [twitterEngine testService]; } - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView { return 1; } - (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component { return [arrayEmotes count]; } - (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { return [arrayEmotes objectAtIndex:row]; } - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { NSLog(@'Selected Color: %@. Index of selected color: %i', [arrayEmotes objectAtIndex:row], row); [btnUpdateMood setEnabled:YES]; } - (IBAction)updateMood:(id)sender { NSLog(@'Tried to send status.'); NSInteger selectedindex = [pickerView selectedRowInComponent:0]; switch(selectedindex){ case 0: //Happy sImageName = @'Happy'; break; case 1: //Sad sImageName = @'Sad'; break; case 2: //Tongue sImageName = @'Tounge'; break; case 3: //Drunk sImageName = @'Drunk'; break; case 4: //Bored sImageName = @'Bored'; break; case 5: //Love sImageName = @'Love'; break; case 6: //Sleepy sImageName = @'Sleepy'; break; case 7: //Sick sImageName = @'Sick'; break; case 8: //Awake sImageName = @'Awake'; break; case 9: //Shocked sImageName = @'Shocked'; break; case 10: //Angry sImageName = @'Angry'; break; case 11: //Laughing sImageName = @'Laughing'; break; case 12: //Dancing sImageName = @'Dancing'; break; case 13: //Confused sImageName = @'Confused'; break; default: break; } [twitterEngine sendUpdate:[@'has changed his/her iMood to ' stringByAppendingString:sImageName]]; } // Override to allow orientations other than the default portrait orientation. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (void)dealloc { //Releasing seems to sometimes cause complete errors. //[twitterEngine release]; [super dealloc]; } #pragma mark MGTwitterEngineDelegate methods - (void)requestSucceeded:(NSString *)requestIdentifier { [activityView stopAnimating]; //Some animations [UIView beginAnimations:@'redToWhite' context:nil]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationDuration:1]; [UIView setAnimationRepeatCount:0]; //Change background colour of the activity area over 1 second [activityArea setBackgroundColor:[UIColor whiteColor]]; [currentActivity setText:@'Logged In']; [UIView commitAnimations]; //End of animations NSLog(@'Request succeeded (%@)', requestIdentifier); if ([requestIdentifier isEqualToString:_testUID]) { NSLog(@'[TWITTER UP]'); } } - (void)requestFailed:(NSString *)requestIdentifier withError:(NSError *)error { currentActivity.text = [NSString stringWithFormat:@'Error: %@ %@', [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]]; NSLog(@'Twitter request failed! (%@) Error: %@ (%@)', requestIdentifier, [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]); } - (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)identifier { NSLog(@'Got statuses:\r%@', statuses); } - (void)directMessagesReceived:(NSArray *)messages forRequest:(NSString *)identifier { NSLog(@'Got direct messages:\r%@', messages); } - (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)identifier { NSLog(@'Got user info:\r%@', userInfo); } - (void)miscInfoReceived:(NSArray *)miscInfo forRequest:(NSString *)identifier { NSLog(@'Got misc info:\r%@', miscInfo); } - (void)imageReceived:(UIImage *)image forRequest:(NSString *)identifier { NSLog(@'Got an image: %@', image); } @end
You have a few leaks (twitterEngine (you are retaining it when alloc/init does the job fine) and arrayEmotes (never gets released) to name the two I spotted right away), and you could have another issue related to sImageName when you send the update (notice how it isn’t defined on a scope other than inside the switch statement – I don’t really know if this would definitely cause issues, it’s just something I always try to avoid. I can see it potentially causing an EXC_BAD_ACCESS).
Anyway, try using GDB to step through your program to figure out what object exactly is being released early. A lot of headaches can be solved simply with GDB.