UITableView didSelectRowAtIndexPath error - when selecting item again - uitableview

Loaded a list of items on to the UITableview and was able to click and show an alert for the row selected . But however after saying "ok" on the alert and i reclick on the already selected row my code breaks down saying "Thread 1:Program received signal:EXC_BAD_ACCESS".please take a look at the code below.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *playerselected = [exercises objectAtIndex:indexPath.row];
NSString *video = [playerselected valueForKey:#"video"];
NSString *msg = [[NSString alloc] initWithFormat:#"You have selected %#", video];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Player selected"
message:msg
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[video release];
[msg release];
}
PLease suggest me what could be the issue here.

Don't release video.
When you retrieve a value from an NSDictionary you don't own it unless you explicitly retain it.
To be more specific, when you retrieve your string it is still owned by the dictionary. When you release it, you are releasing an object that you do not own, resulting in it being over-released. As a result it is deallocated, and when you next try to access it the memory is no longer valid and your app crashes.

Related

Objective-c - validate filled fields before publish item

In my application I send data to server and parse.
But I have to send image and you need to choose category.
When you don't choose category I show for user information.
But: how can I check if the user has filled in all the fields? In my app choose image and category?
This is my code with show error when you don't choose category and send action:
- (IBAction)submitItem:(UIButton *)sender {
if ([category isEqualToString:#""]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Category 'All' is reserved" message:#"You need to choose different category" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
return;
}
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 1.0);
///// send image to server
NSString *urlString = urlSaveFullImageToServer;
Your change could be as simple as using an else statement...
- (IBAction)submitItem:(UIButton *)sender {
if ([category isEqualToString:#""]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Category 'All' is reserved" message:#"You need to choose different category" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
return;
}
else {
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 1.0);
///// send image to server
NSString *urlString = urlSaveFullImageToServer;
...
Personally I think a better approach is not to enable the "send" button until all of the data is complete.
Set the submit button enabled property to NO and then when the various pieces of information are entered (the image, the category) check to see if everything is complete - once it is, set enabled to YES

Obtain an array with notifications

I am trying to put notifications in an array as they become available, but the count of the array is reset to 1 when I push a new notification.
This is the code:
int r = 0;
listMsgReceived = [[NSMutableArray alloc] init];
if (notification)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Notification received" message:[NSString stringWithFormat:#"%#", message] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
[listMsgReceived insertObject:message atIndex:r];
r++;
NSLog(#"apres: %d \n", [listMsgReceived count]);
}
It looks like you are initializing the variables r and listMsgReceived each time your notification is received (though it's hard to tell from the context you provided).
You should not do that, because that gets you a new array each time, where you insert one object - hence the count will be one after each notification.
You could try moving your array initialization outside of your method; declare it as a property on your class and initialize it in the initializer.

UIActionSheet works fine in iOS6 but crashes in iOS7 -- data structures were at fault

EDIT: The error is with the data structures that are being used during PDF generation. I'll be able to debug it once I can get a copy of OSX that supports iOS7. Thanks for all the help everyone!
At work I have Mac dedicated to working on iOS 6 apps. So far it hasn't been possible to update to a newer version of OSX so my version of XCode can't be upgraded to support iOS7 naturally. So long story short I can't debug iOS7 apps, so I am not sure why the app is crashing.
I have a UIActionSheet. I used to be using one with those completion blocks but was trying to debug so I have stripped everything away to just the basic barebones and it still crashes when I click on the button.
UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send by Email", #"Send To...", #"Open In...", nil ];
[actionSheet showFromBarButtonItem:sender animated:YES];
That's just sitting on the end of a PDF generation method.
Any ideas? I've been researching this all afternoon and I haven't found any reason why it would stop working like this. I did try storing the action sheet as data in the view controller so the reference was being kept, but to no avail.
I am using ARC.
EDIT: I tried an UIAlertView with the same results. Maybe it's the PDF context ruining things somehow?
Thanks for all the help everyone.
EDIT: Big breakthrough in solving this one: When commenting out my PDF generation code that's before my action sheet/modal dialog/alert view, it opens without complaint. So it's some kind of hybrid issue, and I'll post the majority of my method here so everybody can see what's up:
-(void)shareTapped:(id)sender
{
if (actionSheet.isVisible)
return;
if (![MFMailComposeViewController canSendMail])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No mail setup" message:#"You must setup your email in the main settings app before you can share." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
for( NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows )
{
// should only get run once due to UI
Calculation* calc = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString *filename = [calc.name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *path = [[[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent:filename] stringByAppendingPathExtension:#"ipc"];
[[PPCalculation sharedInstance] openCalculation:path];
}
[[PPCalculation sharedInstance] calculate];
// let's generate the PDF here!
NSMutableData* pdfData = [[NSMutableData alloc] init];
UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );
UIGraphicsBeginPDFPage();
// 200 lines of drawing commands here
UIGraphicsEndPDFContext();
// save to file
NSString* path;
for( NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows )
{
// should only get run once due to UI
Calculation* calc = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* filename = [calc.name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
path = [[[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent:filename] stringByAppendingPathExtension:#"pdf"];
[[NSFileManager defaultManager] createFileAtPath:path
contents:pdfData
attributes:nil];
}
// ActionSheet, modal dialog, composer dialog, alert view, all of them crash when I try to put them here
UIActionSheet* sheet = [[UIActionSheet alloc] initWithTitle:#"Share" delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send By Email", nil];
[sheet showFromBarButtonItem:sender animated:YES];
}
Thanks again guys.
EDIT: It seems that, from my investigation and commenting things out line by line and sending them to the device over TestFlight that it's the internal data structures somehow not working properly, which is strange, as the rest of the app works fine. I probably will get a copy of Mountain Lion or something so I can debug this thing properly.
Try below code... May be it will help you...
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send by Email", #"Send To...", #"Open In...", nil];
//actionSheet.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
actionSheet.tag = ((UIButton*)sender).tag;
[actionSheet showFromRect:[(UIButton*)sender frame] inView:[(UIButton*)sender superview] animated:YES];
By sheer trial and error and commenting out code, I have narrowed it down to the PDF generation itself. Somewhere in the guts of the C++ data structures something is happening that is making iOS7 sad but the others fine. I've managed to convince the boss to order Mountain Lion so once that arrives I can build for iOS7 directly and debug it properly.
Try This it will help yo
your barbutton action method :
UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle:nil: delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send by Email", #"Send To...", #"Open In...", nil ];
[actionSheet showInView:self.view];

IBAction button crashes when using it the second time without changing view

So I'm building a notes app saving the notes to a NSUSerDefaults after the click of a button. Well when I load that view and add the note and click on the button to save it the first time, it works properly. However if I don't leave the view and add a new message and try to click the button to save it, my app crashes. which I really don't understand why. The xcode version I'm using right now doesn't give me a lot of details on my errors, but I do see this
0x00015a9b <+1175> xor %eax,%eax
Program received signal 'SIGABRT'
This is the code of the IBAction that is triggered after the button click (sent event)
-(IBAction)saveNote{
NSUserDefaults *prefs=[NSUserDefaults standardUserDefaults];
//If empty add text to synthesized array and then add the array to the USer defaults
if([[prefs stringArrayForKey:#"Subjects"] count]==0){
NSLog(#"Went through here");
[notesSubject addObject:writeNote.text];
[prefs setObject:notesSubject forKey:#"Subjects"];
NSLog(#"The length of the array is %d",[notesSubject count]);
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Note Saved" message:#"Your note was saved" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
//[notesView.tableView reloadData];
}
//If not empty, get the array stored in the user defaults and set it to a temp array, add text to that temp array and then place the temp array back to the user defaults.
else{
newSubjects=[[NSMutableArray alloc]init];
beforeSubjects=[[NSArray alloc]init];
newSubjects= [prefs stringArrayForKey:#"Subjects"];
[newSubjects addObject:writeNote.text];
[prefs setObject:newSubjects forKey:#"Subjects"];
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Note Saved" message:#"Your note was saved" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
//[notesView.tableView reloadData];
}
}
Yeah, I don't really understand why the app crashes on second click.
You're overwriting the mutable newSubjects instance with an immutable instance with this line:
newSubjects= [prefs stringArrayForKey:#"Subjects"];
Instead, it should be this:
newSubjects = [[prefs stringArrayForKey:#"Subjects"] mutableCopy];

instruments xcode4 not working?

Im following Ray Wenderlich tutorial for instruments, but I don't know why the profiling is not showing the leaked object??
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString * sushiName = [_sushiTypes objectAtIndex:indexPath.row];
NSString * sushiString = [NSString stringWithFormat:#"%d: %#", indexPath.row, sushiName];
NSString * message = [NSString stringWithFormat:#"Last sushi: %#. Cur sushi: %#", _lastSushiSelected, sushiString];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Sushi Power!"
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alertView show];
//_lastSushiSelected = sushiString; //el que jode, pues lo pone en string deallocada, por strinWithFormat que usa autorelease!
_lastSushiSelected = [sushiString retain];
//[alertView release];
}
Im using the code in the tutorial, and as you can see the alertView is leaking!
But I run it trough instruments leaks, and nothing appears! [also is very very very slow to acknowledge the stop button was pressed to stop the profiling!]
So what is missing??,
thanks a lot!
Frankly, I think it's a bug. Hopefully it'll be fixed soon (I'm using v4.1) but all is not lost. Under the Allocations instrument you can filter which types are displayed. In this image I've told it to show UIAlertView instances. After clicking in the UITableView a couple of times you can see it tells me that there are 2 instances living, which confirms that there is a leak.

Resources