Another "wait_fences: failed to receive reply" Question (UIAlertView) - iphone

There are a number of questions regarding the "wait_fences: failed to receive reply" on this forum already, but none of the proposed solutions work for me (although they did help me to mitigate it).
When my app starts up, I do a reachability check, and if I can't reach the host I'm looking for, I pop up a UIAlertView. Initially I was doing this before I even set up the view controller, but then I learned one of the causes of the "wait_fences" problem is that the responder chain isn't properly set up if you haven't displayed a view yet - so I moved everything down into -viewDidAppear. Basically, this is what I have:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Figure out what the reflections name is, then check to see if it can find it online;
// If it can't, -informUserSiteIsNotReachable is called, below
[self retrieveReflectionByName:self.todaysReflectionName];
[self displayReflectionByName:self.todaysReflectionName];
}
- (void)informUserSiteIsNotReachable
{
SEL messageSelector;
if (NO == [self internetIsReachable]) {
messageSelector = #selector(internetNotAccessible);
} else {
messageSelector = #selector(reflectionsSiteNotAccessible);
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[Strings alertViewTitleWhenSiteIsUnreachable] message:[Strings performSelector:messageSelector] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:NULL];
[alert show];
[alert release];
}
I can't seem to get rid of the wait_fences problem: any suggestions?

Here I also faced the same problem in my projects and I solved the issue which is "wait_fences".
Here you can do one change in your code as follows:
- (void)informUserSiteIsNotReachable
{
SEL messageSelector;
if (NO == [self internetIsReachable]) {
messageSelector = #selector(internetNotAccessible);
} else {
messageSelector = #selector(reflectionsSiteNotAccessible);
}
[NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(Show_AlertMessage) userInfo:nil repeats:NO];
}
- (void) Show_AlertMessage
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[Strings alertViewTitleWhenSiteIsUnreachable] message:[Strings performSelector:messageSelector] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:NULL];
[alert show];
[alert release];
}
This works for me. Hope you get rid of this wait_fences issue soon. Let me know if you still have the problem.

Related

EXC_Bad_Request "only" after calling the uialert 3 or more times

I am a newbie in objective c;
I am getting an error at creating a UIAlertview instantiation statements (UIAlert * myAlert, they are in separate scopes)
I have referred the following stackoverflow entries such as This, this, this too and much more research over the internet.
I am unable to get a break through
Following are my alert calls
This is my view controller code where I have put up the "UIAlertViewDelegate"
#import <UIKit/UIKit.h>
#interface gameFirstViewController : UIViewController<UIAlertViewDelegate>
#end
This is my class declaration
#import <Foundation/Foundation.h>
#interface GameLogic : UIView
//all sorts of various non relevant property declarations
#end
Here is my implementation for the alerts
//action to take when an alert is shown
- (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger) buttonIndex
{ NSLog(#"OK Tapped");
NSUserDefaults *MySettingsData = [NSUserDefaults standardUserDefaults];
row= [MySettingsData integerForKey:#"Row_count"];
col = [MySettingsData integerForKey:#"Column_count"];
if(buttonIndex==0)
{
for(int i=0;i<row;++i)
{
for(int j=0;j<col;++j)
{
myarr[i][j]=0;
}
}
if(_TimerStatus ==1)
{
[mainTimer invalidate];
mainTimer=nil;
_TimerStatus=0;
}
[self super_reset];
[self setNeedsDisplay];
NSLog(#"Game reset");
return;
}
}
//my usage of the alerts at 2 different places
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle: #"GAME OVER"
message:#"You clicked on a mine, tap on ok to reset"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[myAlert performSelectorOnMainThread:#selector(show)
withObject:nil
waitUntilDone:YES];
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle: #"You Won! Whoo Hoo"
message:#"You have successfully dodged every minefield"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[myAlert performSelectorOnMainThread:#selector(show)
withObject:nil
waitUntilDone:YES];
I am not sure where I am going wrong, any help would be great!
Thanks.
The way you are creating the UIAlertView is not safe in ARC. It's fine if you use the object right away, but you're passing it the performSelectorOnMainThread method. ARC may dealloc your myAlert variable by the time the main thread gets to perform the selector. That's likely why you're seeing the EXC_Bad_Request.
Either make myAlert a strong property, so it survives, or delay the creation of the UIAlert until the main thread is able to call the show method. You can do that like this:
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:#"GAME OVER" message:#"You clicked on a mine, tap on ok to reset" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil] show];
});
Note: I removed your double nil for the titles. I don't think that would make a difference, but just in case.

Why is app crashing when showing UIAlertView?

I've implemented the Reachability function in a method that handles all the server requests. I can see through NSLogs that the function works perfectly. However there is never a "pause" within the method which means I can't use the UIAlertView without crashing the program.
I might be going at this the completely wrong way, but I can't find anything else...
Does anybody have an idea of how to get a notification to show somehow?
Thanks in advance
CODE:
-(id) getJson:(NSString *)stringurl{
Reachability * reach = [Reachability reachabilityWithHostname:#"www.google.com"];
NSLog(#"reached %d", reach.isReachable);
if (reach.isReachable == NO) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Passwords don't match."
message:#"The passwords did not match. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}else{
id x =[self getJsonFromHttp:stringurl];
return x;
}
return nil;
}
After moving the discussion to a chat, we discovered that your UIAlertView was being called from a background thread. Never do anything related to updating the UI (User-Interface) in a background thread. The UIAlertView updates the UI by adding a little pop-up dialog, so it should be done on the main thread. Fix by making these changes:
// (1) Create a new method in your .m/.h and move your UIAlertView code to it
-(void)showMyAlert{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Passwords don't match."
message:#"The passwords did not match. Please try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
// (2) In -(id)getJson replace your original UI-related code with a call to your new method
[self performSelectorOnMainThread:#selector(showMyAlert)
withObject:nil
waitUntilDone:YES];

UIAlertViewDelegate not acting as expected

I have a very simple process running where after each round of a simple game the scores are calculated, labels updated and all the normal, very simple stuff. I have a UIAlertView that informs the player of how s/he performed. I use a UIAlertViewDelegate to postpone all the updates, resetting of controls etc. till after the UIAlertView is dismissed. The methods are [startNewRound],[startOver] and [updateLabels]. It's fairly obvious what they all do. Anyway, when the user hits round ten, I've made another UIAlertView that informs the player that the game has ended and shows the overall score. Again, I hoped to use a delegate to postpone the resets till after the AlertView is dismissed. The only problem is, with the endGame AlertView, it seems to be using the first AlertView's delegate method causing the game to continue with a new round and not start from the beginning. I hope this makes sense. Anyway, here are snippets of my code.
if (round == 10){
UIAlertView *endGame = [[UIAlertView alloc]
initWithTitle: #"End of Game"
message: endMessage
delegate:self
cancelButtonTitle:#"New Game"
otherButtonTitles:nil];
[endGame show];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate:self
cancelButtonTitle:#"Next"
otherButtonTitles:nil];
[alertView show];
}
And then the delegate methods:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startNewRound];
[self updateLabels];
}
- (void)endGame:(UIAlertView *)endGame didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startOver];
}
So there it is. As I mentioned, the endGame AlertView appears to be using alertView's delegate, thus not activating the [self startOver] method. All the methods are working, it's just the AlertView is using the incorrect delegate method. Regards, Mike
Change your code like this,
if (round == 10){
UIAlertView *endGame = [[UIAlertView alloc]
initWithTitle: #"End of Game"
message: endMessage
delegate:self
cancelButtonTitle:#"New Game"
otherButtonTitles:nil];
endGame.tag = 111;
[endGame show];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate:self
cancelButtonTitle:#"Next"
otherButtonTitles:nil];
alertView.tag = 222;
[alertView show];
}
and delegate method as,
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if(alertView.tag == 111)
{
[self startNewRound];
[self updateLabels];
}
else if(alertView.tag == 222)
{
[self startOver];
}
}
You cant have two delegate method for dismisswithbuttonindex, you need to handle this situation with tag.
Give both alert view a different tag and check it on delegate object. Thus you can differentiat the both alert view.

TWTweetComposeViewController freezes my app completely on alloc-init

I've got an iPhone app that uses the Twitter framework in iOS 5. I've noticed that when I try to tweet something, the app completely freezes on the "alloc init" line of code.
Here's my code. Anybody see something wrong with it?
-(void)tweet {
NSLog(#"Tweeting");
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
if (stringToShare.length < 140) {
TWTweetComposeViewController *tweetController = [[TWTweetComposeViewController alloc] init];
[tweetController setInitialText:stringToShare];
[self presentModalViewController:tweetController animated:YES];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Easy there, Hemingway." message:[NSString stringWithFormat:#"Your note has %d characters, which exceeds Twitter's limit of 140.", stringToShare.length]delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
UPDATE: This method is called from a modal view controller. Could that be the issue?
UPDATE 2: Here's the line of code that's used to detect if the user can tweet:
if ([TWTweetComposeViewController canSendTweet]) {
[availableActions addObject:#"Tweet"];
}
I know that the issue is not constant --- it seems to occur on my phone, but not my co-founder's.

Xcode - Help implementing some code into a view based app?

Can someone help me with implementing this code into a view based app?
This is the code that I have:
- (void)webViewUIWebView *)newsweb didFailLoadWithErrorNSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Error1!" message:#"Please confirm network connectivity and try again!" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
}
With this code and any other code that I may need, but don't know, I would like to know what code to implement into the .h + .m view controller files.
What I am trying to achieve is an error after starting the app if there is no network connection available. What I'm worried about also but not quite sure if it will happen, is that this will repeat the error "x" times for how many UIViews I have. If that would be the case could you also help me should that it would only show the error once.
Put a Boolean in your header file, and when the alert fires, change it. If the Boolean is false, then simply don't show the alert.
#interface
BOOL alertShown;
#end
#implementation
-(void)applicationDidFinishLaunching{
alertShown = NO;
}
-(void)webViewError{
if(alertShown == NO){
//show the alert
alertShown = YES;
}
}
#end