0 objc_msgsend.. when i click Ok Button on alertview .. clickedButtonAtIndex [closed] - ios

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
When i pressed ok button that time application is crash due to 0 objc_msgsend ?
-(void)onBusinessSuccess:(id)dataObj
{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Order" message:#"Order Successfully Discontinued." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
alertView.tag = 1;
[alertView show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
NSLog(#"I am cliked");
}
}

From the comments (added to an answer to others benefit):
When you crash on a "objc_msgSend()" you are most likely sending a messageto an already-freed object. Or you have a pointer, which is correct, but something have changed the objects contents.  Another cause can be the use of a dangling pointer that once pointed to the memory now occupied by your object. Occasionally objc_msgSend crashes because a memory error changed the runtime's own data structures, which then would cause trouble in the receiver object itself.
In this situation you need to check wheter or not, the delegate of the UIAlertview has been released after presenting, so when the alert is dismissed, it is not sending a message to it's delegate, which may be nil. An other option is that the UIViewController that presents the alert view is released after it is presented. Please check if the alert delegate is not released after it is presented. 

Related

Understanding a strong pointer and out of scope

I wanted to understand the following scenario
-(void) foo
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not save file"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//This is called when ok is pressed
}
In the above code a UIAlertView strong pointer is created and a delegate to self is assigned. The reason I called it a strong reference pointer is because it is created in scope and will go out of scope when its reference count goes to 0. I believe the reference count goes to 0 when the method foo ends then why am I still getting a callback at clickedButtonAtIndex ? I was under the assumption that we would not get a callback because the destructor of the alertView instance would have been called as soon as the method foo ended.
I believe the reference count goes to 0
You believe wrong. When you say [alert show], you hand the alert object over to Cocoa, which retains it; otherwise there would be no alert view to appear on the screen! That alert view has a reference (which is actually weak) to you (self). And Cocoa thus is able to hand the very same alert view back to you in the delegate callback; the alert is still alive because Cocoa is still retaining it, and you are still alive because you are still alive, so the reference to self works as the target of the callback.
Also, I can't quite tell whether you grasp that as soon as you say [alert show], the code does not pause - it goes right on, immediately. Thus the first method is over before the alert actually appears on the screen. Again, this works because the alert has been handed over to Cocoa, which retains it and takes care of showing it on the next runloop. None of your code is running while the alert is present on the screen.
A completely parallel situation is
MyViewController* vc = [MyViewController new];
[self.presentViewController:vc animated:YES completion:nil];
The code ends, so why doesn't MyViewController vanish in a puff of smoke? Because presentViewController hands it over to Cocoa, which inserts it into the view controller hierarchy and retains it.

How to remove a specific object from an array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
So I'm currently making a calorie tracker. In this app, you enter the recent meal you ate, and the amount of calories in that meal. Then you press the "add" button. This button will save the data to a TableView called HistoryTableViewController. To check if the person has left a textfield blank, I have 3 "if statement". One looks like this:
if ([[self.amountText.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] < 1)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning!" message:#"You have not entered the amount of Calories!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[amountHistory removeObjectAtIndex:0];
}
There is one line of code that I know is wrong which is the
[amountHistory removeObjectAtIndex:0];
I don't necessarily want to remove the first object on the tableview, I just want to make sure that the item doesn't get added.
Thanks in advance.
EDIT:
I add an object to the array at the top of the if statements:
total+= self.amountText.text.intValue;
self.totalLabel.text = [NSString stringWithFormat:#"%d", total];
NSNumber *calorieNumber = [NSNumber numberWithInt:self.amountText.text.intValue];
NSString *foodString = nameOfTheFood.text;
NSString *historyString = [NSString stringWithFormat:#"%# Calories in %#", calorieNumber, foodString];
[amountHistory addObject:historyString];
Sounds like you are thinking about it from the wrong angle.
Instead of adding the item to your array and then removing it if it is invalid, you should ensure the item is only added when it is valid.
So in your method you would only add the item at the end, after all validation has passed. You would add early return's in your if statements if the any validation fails so that you don't reach the code that adds the item to the array
The answer to your subject:
How to remove a specific object from an array
is
[array removeObject:obj];
Note, this uses the isEqual message on the object to determine equality. If you want specific object equality, use removeObjectIdenticalTo: instead.
Source: Apple Docs on NSMutableArray
If you are looking to remove the last item in the array use:
[amountHistory removeLastObject];
But if your issue is that you don't want to add blank items to the array why not check if they are blank before adding them?
You can only remove objects from an array if you are using NSMutableArray. Have a read of the NSMutableArray Class Reference

when i set delegate.self in uialertview application is crash in arc

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Order"
message:#"Order Successfully Discontinued."
delegate:self
cancelButtonTitle:nil
otherButtonTitles: #"Ok",nil];
//[alertView performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:YES];
alertView.tag=TAG_DEV;
[alertView show];
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
if(alertView.tag==TAG_DEV)
{
if(buttonIndex==0)
{
}
else
NSLog(#"Here");
}
}
This crashes. How can I fix it?
When you crash on a "objc_msgSend()" you are most likely sending a messageto an already-freed object. Or you have a pointer, which is correct, but something have changed the objects contents. Another cause can be the use of a dangling pointer that once pointed to the memory now occupied by your object. Occasionally objc_msgSend crashes because a memory error changed the runtime's own data structures, which then would cause trouble in the receiver object itself.
In this situation you need to check wheter or not, the delegate of the UIAlertview has been released after presenting, so when the alert is dismissed, it is not sending a message to it's delegate, which may be nil. An other option is that the UIViewController that presents the alert view is released after it is presented. Please check if the alert delegate is not released after it is presented.

UIAlertView with timer [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm trying to make a UIAlertView with a timer. For example: The user sets a time, the user taps a button, a UIAlertView pops up and in the alertView there is a timer showing how long the user has to wait before an action will start.
When searching the web I only found how to show how much time has passed. Is there a way to update the UIAlertView every second to show the timer? After the time has passed, the UIAlertView needs to be dismissed and a void has to be called.
try like it.
UIAlertView *autosaveAlert = [[UIAlertView alloc]initWithTitle:#"Close" message:#"Autosave in (%d) seconds" delegate:self cancelButtonTitle:#"Press to cancel" otherButtonTitles:nil];
[autosaveAlert show];
for(int i = 10; i>=0; i--){
NSString *tmp = #"Close in (%d) seconds";
NSString *str = [NSString stringWithFormat:tmp, i];
[autosaveAlert setMessage:str];
CFRunLoopRunInMode(kCFRunLoopDefaultMode,1, false);
}
[autosaveAlert dismissWithClickedButtonIndex:0 animated:TRUE];
Yes, you can keep a pointer to the alert view & modify its message, title & dismiss it with any button index you choose. Refer to the UIAlertView class reference document for proper method names.

Dynamic cast to a custom class in objective C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
In NewTaskViewController.h, delegate was declared to be a property of type id.
Does the typecast below make delegate point to the object of type ViewController?
#import "NewTaskViewController.h"
#import "ViewController.h"
#implementation NewTaskViewController
- (IBAction)saveTask:(id)sender {
if ([self.textField.text length] == 0)
return;
ViewController *tasksListView = (ViewController *)self.delegate;
[tasksListView.tasks addObject:self.textField.text];
[self close:sender];
}
- (IBAction)close:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
The cast tells the compiler that you want to use the delegate object as if it were a ViewController. If it really is one, you're OK. If it's not, bad things will happen at run-time. That is, the cast doesn't do any kind of conversion.

Resources