UIAlertview exc_bad_access [duplicate] - ios

This question already has answers here:
UIAlertView fails to show and results in “EXC_BAD_ACCESS” error
(6 answers)
Closed 8 years ago.
I add a function to dismiss the UIAlertView after several seconds.The whole code is like:
- (void)netWorkAlert
{
UIAlertView *netWork = [[UIAlertView alloc] initWithTitle:#"error" message:#"network has problems" delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[netWork show];
[self performSelector:#selector(dismissAlert:) withObject:netWork afterDelay:2];
}
- (void)dismissAlert:(UIAlertView *)alert
{
if(alert)
{
[alert dismissWithClickedButtonIndex:0 animated:YES];
[alert release];
}
}
the netWorkAlert is invoked when the network is unavailable.
Now the problem I met is when the netWorkAlert is invoked at the second time, the app is broken and the Xcode shows error in
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([ZJAppDelegate class]));
//Thread 1 :EXC_BAD_ACCESS(code=1,address=xc0000004)
}
}
I didn;t use ARC and I don't know why it crashes. Even I comment the [alert release];, it still has the same problem at the second time.
Could anyone help me to check it?
thanks!

The EXC_BAD_ACCESS is caused by accessing a released object. To avoid this make your call to UIAlertView kind of modal:
Function body:
-(void)checkSaving
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Do you want to add these results to your database?"
message:#"\n\n"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Save", nil];
alert.alertViewStyle = UIAlertViewStyleDefault;
[alert show];
//this prevent the ARC to clean up :
NSRunLoop *rl = [NSRunLoop currentRunLoop];
NSDate *d;
d= (NSDate*)[d init];
while ([alert isVisible]) {
[rl runUntilDate:d];
}
}
Your choice result:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 1)//Save
{
//do something
}
if (buttonIndex == 0)//NO
{
//do something
}
}
Register the functions in the interface declaration:
#interface yourViewController ()
-(void)checkSaving
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
//...
#end
To call:
[self checkSaving];
I wish this will help you.

The UIAlertView could be out of scope by the time the dismissAlert method is called (your checking for alert being nil will prevent this code crashing. There is, however, a better way of implementing this where alert will never be out of scope.
Your class that defines the networkAlert method should implement the <UIAlertViewDelegate> protocol. The code below allows you to intercept the user clicking the 'cancel' button and perform a custom action. The default action of pressing cancel is to close the UIAlertView.
#interface YourClassName : UIViewController <UIAlertViewDelegate> {}
#implementation YourClassName
-(void) networkAlert
{
UIAlertView *netWork = [[UIAlertView alloc] initWithTitle:#"error"
message:#"network has problems"
delegate:self
cancelButtonTitle:#"cancel"
otherButtonTitles:nil];
[netWork show];
}
- (void) alertViewCancel:(UIAlertView*)alertView
{
what ever it is you want to do when the cancel button is pressed here
}

Related

Change iOS tab view from alert

I have a tabbed application with 2 tab views. I want to change the view from the second tab to the first when the user presses "OK" on an alert view.
The following code snippet works when I use it on an -IBAction button pressed, but it doesn't do anything when I use it inside the alert code:
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
Why does it not work when used as below, in my SeondViewController.m in my
- (void)viewDidLoad {
[super viewDidLoad];?
UIAlertView *alert =[[UIAlertView alloc]
initWithTitle:#"Camera and Target coincident"
message:msg
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
I'm just learning this, so anything you can offer would be helpful.
When I use the following code:
if ([ theProjection Trans_Initialise] == 1) {
NSString * msg = nil;
UIAlertView *alertView =[[UIAlertView alloc] initWithTitle:#"Camera and Target coincident" message:msg delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:#"OK"]) {
self.tabBarController.selectedIndex = 0;
}
}
I get the error message on -(void) alertView "Invalid argument type void to unary expression" Am I doing something grammatical, or is it (quite possibly) something I just didn't understand?
First of all, you need a delegate call back from the alert view informing you about the button that was clicked.
Your alert view should be created like this :
UIAlertView *alert =[[UIAlertView alloc] initWithTitle:#"Camera and Target coincident" message:msg delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
Then in your m file implement the function :
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:#"OK"]) {
self.tabBarController.selectedIndex = 0;
}
}

UIAlertView showing up on Simulator, but not device

I have UIAlertView working as expected in simulator, and earlier in my App's development it worked well on the device, but as of now it doesn't show up. I am however certain the code is running. Help would be greatly appreciated.
MacroEditViewController.h:
#interface MacroEditViewController : UIViewController <UIAlertViewDelegate>
MacoEditViewController.m:
- (IBAction)saveDatabase:(UIButton *)sender
{
[self alertStatusWithTitle:[NSString stringWithFormat:#"Are you sure you want to override %# for %#? This cannot be undone (But you can Reset All Overrides on Macros screen).", macroMeal[1], macroMeal[0]] :#"Update Macros"];
}
- (void) alertStatus:(NSString *)msg :(NSString *)title
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:#"Cancel", nil];
[alertView show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
[self saveUpdatesToDatabase];
}
}
Why did you call your function like this
[self alertStatus:[#"Are you sure you want to override?"] :#"Update Macros"];
Call it like this
[self alertStatus:#"Are you sure you want to override?" :#"Update Macros"];
without the square brackets, it may be the problem
create a CIAlert.h
void CIAlert(NSString* title, NSString* alert);
void CIError(NSString* error);
and in CIAlert.m
#import "CIAlert.h"
void CIAlert(NSString* title, NSString* alert) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:title message:alert delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
void CIError(NSString* error) {
CIAlert(#"Error", error);
}
import the class CIAlert.h and call it just like this...
CIAlert(#"Title", #"Enter your message");

how to get UIAlertView otherButtons' title?

-(void) alertView: (UIAlertView *) alertVw clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *str = [NSString stringWithFormat:#"%d 。", buttonIndex];
UIAlertView *newAlertVw = [[UIAlertView alloc] initWithTitle:#"INFO" message:str delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[newAlertVw show];
}
UIAlertView *alertVw = [[UIAlertView alloc] initWithTitle:#"TITLE"
message:#"box message"
delegate:self
cancelButtonTitle:#"hide"
otherButtonTitles:#"T1", #"T2", nil];
[alertVw show];
if user touched the one of otherButtons, yes, we know which button that user touched.
then, how can I to get the title of button that user just touched?
thanks.
With the delegate on your UIAlertView set to self you can use this:
-(void)alertView:(UIAlertView*)alertView didDismissWithButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(#"Button Title -----> %#",[alertView buttonTitleAtIndex:buttonIndex]);
// or you can check if it equals to string
if([[alertView buttonTitleAtIndex:buttonIndex]isEqual:#"Enter"])
{
// your code goes here
}
}
The method is buttonTitleAtIndex: and the info is simply found on the UIAlertView doc page.
https://developer.apple.com/library/ios/documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html#//apple_ref/occ/instm/UIAlertView/buttonTitleAtIndex:
I advise you to refer to the doc as often as you can this is how you will learn and remember.
Actually, if you want to use the delegate method you have to use -(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex.
and not
-(void)alertView:(UIAlertView*)alertView didDismissWithButton At Index:(NSInteger)buttonIndex
see: https://developer.apple.com/library/ios/documentation/uikit/reference/UIAlertViewDelegate_Protocol/UIAlertViewDelegate/UIAlertViewDelegate.html#//apple_ref/occ/intfm/UIAlertViewDelegate/alertView:didDismissWithButtonIndex:
I guess it was just a typo of Pancho.

UIAlertView not responding to button event

First time working with UIAlertViews and I can't figure out why this doesn't work. When I click on either button, the alert closes, but there is no NSLog output. What am I doing wrong? I can't figure it out. Thanks!
.h
#interface LoginViewController : UIViewController <UIAlertViewDelegate>
#end
.m
- (IBAction)resetPassword:(UIButton *)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Password Reset"
message:#"A temporary password will be sent to you at the address we have on file."
delegate:nil
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Reset Password", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) NSLog(#"button 0");
if (buttonIndex == 1) NSLog(#"button 1");
}
It appears that you never set the delegate on the UIAlertView. It should be:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Password Reset"
message:#"A temporary password will be sent to you at the address we have on file."
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Reset Password", nil];
This way the UIAlertView is able to call your method, - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex, when the user taps a button.
You're setting the delegate to nil. You need to set it to your controller instance, like this:
- (IBAction)resetPassword:(UIButton *)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Password Reset"
message:#"A temporary password will be sent to you at the address we have on file."
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Reset Password", nil];
[alert show];
}
Implementing the -alertView:clickedButtonAtIndex: delegate method does little good if you never give the UIAlertView an object to serve as the delegate.

UIalertView dosen't call alertView:clickedButtonAtIndex

I have a class called MatchmakingServer has a method as following:
- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state
{
switch (state)
{
case GKPeerStateAvailable:
break;
case GKPeerStateUnavailable:
break;
// A new client has connected to the server.
case GKPeerStateConnected:
if (_serverState == ServerStateAcceptingConnections)
{
if (![_connectedClients containsObject:peerID])
{
NSString *peerID2 =[self displayNameForPeerID:peerID];
self.PeerId=peerID;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Oops:("
message:[NSString stringWithFormat:#"%#:%# %#",#"device",peerID2,#"want to join your session"]
delegate:self
cancelButtonTitle:#"NO"
otherButtonTitles:nil];
[_connectedClients addObject:peerID];
NSLog(#"the orginal peerID %#",peerID);
[self.delegate matchmakingServer:self clientDidConnect:peerID];
}
}
also
#interface MatchmakingServer : NSObject <GKSessionDelegate,UIAlertViewDelegate>
Any Ideas why alertView dosn't call the clickedButtonAtIndex
You're not showing the alert view on the screen, you're only initializing it. Insert
[alert show];
after the initialization code and you should be fine.
You need to call [alert show]; method and adopt UIAlertViewDelegate in your UIViewController.h file.

Resources