on iOS5 I can use method to show UIAlertView:
[alert performSelectorInBackground: # selector (show) withObject: nil];
on iOS6 crash my app, why?
That the replacing?
Thanks
Why are you performing that selector in the background? Showing an alert view probably isn't something you want to be doing on a background thread.
You aren't suppose to do UI stuff in the background. It will make your app crash. You normally do stuff like loading data from a server in the background or computational expensive operation, but never do anything that's in the UIKit framework in a background thread.
Related
I discovered performSelectorInBackground: a couple days ago, and I immediately knew a spot in my app where this would be perfect.
- (void)activate {
waitForStartCode.text = #"Loading...";
userNotifications.text = #"";
timeRemaining.text = #"";
[loadingNTP startAnimating];
[self performSelectorInBackground:#selector(initializeEverything) withObject:nil];
}
This is called when my view is visible. Before, while the NTP time servers were being connected to using CocoaAsyncSocket, my app froze until this process was completed. I really want a loading view with an animated UIActivityIndicatorView.
Everything in the initializeEverything -(void) works fine, exept the NTP initialization using CocoaAsyncSocket.
[NetworkClock sharedNetworkClock];
I get a :
Even with my unskilled eye, I could tell that CocoaAsyncSocket was not meant to be run in the background.
Is there any way around this?
CocoaAsyncSocket supports asynchronous networking. So in principle you do not need a background thread yourself to prevent your UI from freezing: CocoaAsyncSocket will handle communication in background for you.
I cannot say if you are using the framework in a "blocking" way or you are doing anything else that is making your UI block. But, as I said, in principle you do not need to manage a background thread yourself.
I need to run some database processing when my app first starts once a day.
I elected to do this in my first view and showed an alertview with an activity indicator. I tried using NSThread detachNewThreadSelector to run the db processing. At the end of the function I used dismissWithClickedButtonIndex to dismiss the alert view.
I then called the view controller from applicationWillEnterForeground if the date permitted.
However, I'm getting an error Tried to obtain the web lock from a thread other than the main thread or the web thread. Crashing now, on the dismissWithClickedButtonIndex line.
I believe this is occurring due to a flaw in using an object like an alertview with a thread.
I need this to be iOS 4 compatible.
Can anyone point me at an alternative approach ?
You won't be able to create and work directly with the UIAlertView in a background thread.
Here's a skeletal idea of what you could do:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
// create your progress indicator in your alert view
[alertView show];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do your db update
dispatch_async(dispatch_get_main_queue(), ^{
// update your alert view here.
});
});
The idea is to do your processing on a background queue and message back to the main queue for objects that are main-thread only (like UIAlertView.)
I want to show the UIAlertView when user Click the Iphone Home button( means Close the application)
I have done these Code
- (void)applicationWillTerminate:(UIApplication *)application
{
NSString *errorString =#"Testing";
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Alert" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
}
But UIAlertView is not Showing. please help
Thanks in Advance
The user aims to close your app when he/she presses the home button. Apple suggest to let him/her to that. What I want to say: Don't do that. I think it is even not possible.
Look at Problem with applicationShouldTerminate on iPhone:
The alert view is never shown because
the 'show' method does not block, and
therefore, the end of
'applicationWillTerminate' is reached
immediately after you create the
alert view and try to show it. I
believe this is by design. You can't
really begin asynchronous operations
in 'applicationWillTerminate'.
applicationWillTerminate: may not be called in the newer version of iOS when pressing the Home button because the app could be only entering the background mode, not actually terminating.
Even if it is actually called (either the app is really terminated, or you're moving the code to applicationWillEnterForeground:), showing the alert is useless because the alert is associated with the active app, and your app has gone inactive by the time the alert is shown! So what happened really is, the alert is gone when the user press the home button, and when they resume your app, they see a mysterious alert popping up.
Don't ask if the user wants to quit your app. This isn't the norm in iOS. Instead, save all states in applicationDidEnterBackground:, and restore them in applicationWillEnterForeground: and application:didFinishLaunchingWithOptions:, making the user feel as if the app has never been terminated.
You might not want to use applicationWillTerminate but rather applicationWillResignActive. Check older posts like this one for more info.
You can't show a uialertview when application receive SIGKILL(Exit) Command.You can call any file or background functions in applicationWillTerminate - To do that you need to set a key in your plist.
UIApplicationExitsOnSuspend - Boolean - YES.
I had the UIActivityIndicatorView working fine in simulator and other 3.0 devices in my app. But I found out that it was not spinning (or showing) in the new iphone 4. Basically I need to show the activity indicator when a button is clicked and hide it when the button click event is complete. I was using the approach below.
[NSThread detachNewThreadSelector: #selector(spinBegin) toTarget:self withObject:nil];
from this link. As mentioned, it correctly spins the activity indicator on all except 4.*.. not sure why. To get around this, I also followed another approach something like (from developer.apple.com)
`
(IBAction)syncOnThreadAction:(id)sender
{
[self willStartJob];
[self performSelectorInBackground:
#selector(inThreadStartDoJob:)
withObject:theJobToDo
];
}
(void)inThreadStartDoJob:(id)theJobToDo
{
NSAutoreleasePool * pool;
NSString * status;
pool = [[NSAutoreleasePool alloc] init];
assert(pool != nil);
status = [... do long running job specified by theJobToDo ...]
[self performSelectorOnMainThread:
#selector(didStopJobWithStatus:)
withObject:status
waitUntilDone:NO
];
[pool drain];
}
`
The problem with this was that, it is showing the acitivityVIewIndicator spinning correctly (at least on the simulator) but after it stops, the built in activity indicator in the top bar (where it shows the battery% etc) is still spinning.
I'm new to objective C. I have finished my app completely but for this silly thing. I realize there is no way to display UIActivityView without starting another thread. and finally, just to rant, I don't understand why they have to make it so complicated. I mean they knew it was going to have this problem, why not provide a sample code everyone can use rather than deriving their own solutions.
Finally, can anyone please provide me with a direction or some sample code. I would really appreciate it. I have been searching for a few hours now and have not found anything really that works!
Why are you starting/stopping the indicator on a separate thread? Any methods you send to your UIActivityIndicatorView must be sent on the main (UI) thread.
Any events sent by a button pressed will automatically be run on the main thread. If you're using background threads to complete the process, you could do something like:
- (IBAction)buttonPressed:(id)sender {
// This runs on the main thread
[activityIndicator startAnimating];
[self performSelectorInBackground:#selector(inThreadStartDoJob:) withObject:theJobToDo];
}
- (void)inThreadStartDoJob:(id)theJobToDo {
// Set up autorelease pool
...
// Run your long-running action
...
// Stop the spinner. Since we're in a background thread,
// we need to push this to the UI Thread
[activityIndicator performSelectorOnMainThread:#selector(stopAnimating) withObject:nil waitUntilDone:YES];
}
Edit: As for the activity indicator in the top bar (where the battery is), doesn't this automatically start/stop based on network activity?
I'm working on an app right now that was working fine until I started implementing some threading for background loading of images. Now theres no crashes but the keyboard does not display. That is to say its invisible (I can still type, I just cant see the actual keyboard).
The only thing I've done was implement threading so I'm wondering if I'm somehow messing with the thread the keyboard runs on or something?
The threads I'm calling are like:
[NSThread detachNewThreadSelector:#selector(loadWebView:)
toTarget:self withObject:[NSNumber numberWithInt:pageNum]];
and
[scrollView performSelectorOnMainThread:#selector(addSubview:)
withObject:curWebView waitUntilDone:NO];
Thanks in advance.
UIWebViews (and all UI elements) cannot be used on background threads safely. If you wish to load images in the background, use NSURLConnection's asynchronous loading methods.