Slow default access crash in iOS - ios

I have been programming for 3 years on iOS, heavily using core data. However, I have never come across a crash like this before and have no idea why this is occurring. This current app is only 4 very simple view controllers, saving to nsdefaults only about 5 different times. The error I am confused on is "Slow defaults access for key ClientState took 0.037632 seconds, tolerance is 0.020000". I have noted where in my code it says the problem is in my code. Also, this is long after the view controller has loaded. This process occurs after a button press. Lastly, this crash only happens half the time, meaning there are occasions when the code actually works without a crash.
NSUserDefaults *ab = [NSUserDefaults standardUserDefaults];
NSString *frcrat = [ab objectForKey:#"frcrat"];
NSString *lapper = [alertView textFieldAtIndex:0].text;
spinner.hidden = NO;
[spinner startAnimating];
delem = NULL;
delem = [[NSMutableArray alloc] init]; //Line after this line gives error Thread 1: Exc_bad_access (code = 1, address=0xe0bb2f85)
NSString *urlString = [[NSString stringWithFormat:#"http://www.mywebsite.com/enum.php?fracat=%#&num=%#&sap=%#", frcrat, lapper, _sna]stringByAddingPercentEscapesUsingEncoding : NSUTF8StringEncoding ];
NSXMLParser *Parser = [[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]] autorelease];
[Parser setDelegate:self];
[Parser parse];

I assume this code is placed somewhere in your view controller initialization.
The warning you're getting means that it's taking too long for the view controller to load, and this is clearly due to the initWithContentsOfURL: call in your code.
As you can read here, initWithContentsOfURL: is blocking, meaning that you should never call it on the main thread. You should perform the XML parser initialization asynchronously. Something like:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *urlString = [[NSString stringWithFormat:#"http://www.mywebsite.com/enum.php?fracat=%#&num=%#&sap=%#", frcrat, lapper, _sna]stringByAddingPercentEscapesUsingEncoding : NSUTF8StringEncoding ];
NSXMLParser *parser = [[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]] autorelease];
[parser setDelegate:self];
[parser parse];
}

It was not even related to nsuser defaults. It was because of the string _sna. I instead saved that string in nsuserdefaults and reloaded it when I needed it as NSString *snameri. Thanks apple debugger for giving me an inappropriate error.

Related

onclicking menu it hangs for some time and then goes to secondview controller

I have made application where I have menu. On clicking menu button, it will go to respective view controller.
Today I added newviewcontroller where I have data coming from online server and I am showing that data in UITableView.
But what weird happening is when I click on button, it hangs for some time (in this hang time it fetches all the data for newviewcontroller) and then come on newviewcontroller.
Note: For fetching data, I have all code in newviewcontroller.
Any idea why this is happening?
For fetching the data, I have code which is exactly same as in below link.
http://www.appcoda.com/ios-programming-rss-reader-tutorial/
for going from first view controller to newviewcontroller, below is code I have.
DoctorsListViewController *secondView = [self.storyboard instantiateViewControllerWithIdentifier:#"doctorsen"];
secondView.myMainURL = #"my url here";
[self.navigationController pushViewController:secondView animated:YES];
Below is what I have in my viewDidLoad of newviewcontroller (doctorlistviewcontroller)
startNumberLabel.text = #"0";
typeNumber = #"0";
feeds = [[NSMutableArray alloc] init];
NSString *myTMainURL = [NSString stringWithFormat:#"%#?type=%#&index=%#", myMainURL, typeNumber, startNumberLabel.text];
NSURL *url = [NSURL URLWithString:myTMainURL];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
As per the Example in the link
startNumberLabel.text = #"0";
typeNumber = #"0";
feeds = [[NSMutableArray alloc] init];
NSString *myTMainURL = [NSString stringWithFormat:#"%#?type=%#&index=%#", myMainURL, typeNumber, startNumberLabel.text];
NSURL *url = [NSURL URLWithString:myTMainURL];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
you have the data that is loaded synchronously that's the reason the the viewController takes time to load and after it has loaded all the data it is loaded and displayed.
So, you can download all the data asynchronously or in a thread and then after the data is downloaded and parsed; Update the View or reload the tableView(if using)
Here is the link to Download data Asynchronously
after you have done that Implement one of the following
1) Apple's reachability
2) Tony Millio's Reachability
and check network status then host status(So that you can display proper message etc) and then call the URL.

For-Loop to quick to present View Controller

i want to add multiple passbook passes by running through a array with URLs. The problem is that the loop counts faster than the view controller can present.
Here s my code:
NSArray *passURLArray = [NSArray new];
passURLArray = response;
for (int i = 0; passURLArray.count; i++) {
NSString *passURLString = [NSString stringWithFormat:#"http://test.de%#", [passURLArray objectAtIndex:i]];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:passURLString]];
NSError *error;
PKPass *pass = [[PKPass alloc] initWithData:data error:&error];
[[UIApplication sharedApplication] openURL:[pass passURL]];
PKAddPassesViewController *passVC = [[PKAddPassesViewController alloc] initWithPass:pass];
passVC.delegate = self;
[passVC setDelegate:(id)self];
[self presentViewController:passVC animated:YES completion:nil];
}
I get this error message:
Attempt to present PKAddPassesViewController: 0xca5f7d0 on
PaymentViewController: 0x14882290 which is waiting for a delayed
presention of PKAddPassesViewController: 0xb169470 to complete
Thanks in advance.
Check if you're on the last iteration of the loop. If you are, animate the display, if not, don't animate it.
That said, it's nasty from a user standpoint. You should probably think about a nicer way of presenting, like showing a list or animating between each display when addPassesViewControllerDidFinish: is called.

NSURL Request? Registration and Login

Here is my code:
//login method
- (int) authenticateClient {
NSString *loginWeb = [NSString stringWithFormat:(#"http://192.168.118.1/login.php?uname=%#&pass=%#&submit=Log%%20In"), user, pass];
NSURL *login = [NSURL URLWithString:loginWeb];
NSData *loginData = [NSData dataWithContentsOfURL: login];
NSString *result = [[NSString alloc] initWithData:loginData encoding:NSUTF8StringEncoding];
NSMutableURLRequest *loginRequest = [[NSMutableURLRequest alloc] init];
[loginRequest setURL:login];
[loginRequest setTimeoutInterval:1];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:loginRequest delegate:self startImmediately:YES];
[connection start];
return [result integerValue];
}
My question is, when simulating having no network connection, my app freezes up and doesn't load or time out in the specified interval (1 second just to see if it works).
I read something about start immediately forces in to run on the current threat causing everything else to "pause" until the action is complete.
I have two questions:
1.) What is a better method to have the URL basically run in the background instead of pausing everything?
2.) How can I get a timeout method that actually works?
Much appreciation! Thanks!
Well, one second as timeout is really low. If you want to simulate different network conditions, you can use something like this. You don't need to this dance:
NSData *loginData = [NSData dataWithContentsOfURL: login];
NSString *result = [[NSString alloc] initWithData:loginData encoding:NSUTF8StringEncoding];
You don't need this as well, since the connection has started already:
[connection start];
Also from the documentation:
NSURLConnection’s delegate methods—defined by the
NSURLConnectionDelegate Protocol protocol—allow an object to receive
informational callbacks about the asynchronous load of a URL request.
Other delegate methods provide facilities that allow the delegate to
customize the process of performing an asynchronous URL load. These
delegate methods are called on the thread that started the
asynchronous load operation for the associated NSURLConnection object.
So for your questions:
Implement the NSURLConnection’s delegate
Check this & this.

I want to give a priority each background thread and excute gradually

This code generates Low memory warning because background 5 thread is almostly loading images in same time.
I want to give a priority each thread and make lock & unlock.
I would make step by step thread. image 1 loading -> image2 loading -> image3 loading -> image4 loading.
How can I do this?
viewcontroller
-(void)viewDidLoad
{
for(int i=0; i<screenshotcount ; i++)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString * url=[detailItem.mScreenshot objectAtIndex:i];
NSDictionary *args=[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:i], #"screenNum",
[NSString stringWithString:url],#"url",
nil];
[self performSelectorInBackground:#selector(loadImageScreenshot:) withObject:args];
[pool release];
}
}
loading image
-(void) loadImageScreenshot:(NSDictionary *) args
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * screenshotImage=[UIImage imageWithStringURL:url];
NSDictionary *args2=[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:num], #"screenNum",
screenshotImage,#"image",
nil];
[self performSelectorOnMainThread:#selector(assignImageToScreenshotImageView:) withObject:args2 waitUntilDone:YES];
[pool release];
}
image add
- (void) assignImageToScreenshotImageView:(NSDictionary *)arg
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * image= [arg objectForKey:#"image"];
UIImageView *imageview=[UIImageView alloc]init];
.
.
imageview.image=image;
[self.mScreenshotSpace addSubview:imageview];
[imageview release];
[pool release];
}
image from url
+(UIImage *)imageWithStringURL:(NSString *)strURL
{
NSURL *url =[NSURL URLWithString:strURL];
NSData * data=[[NSData alloc]initWithContentsOfURL:url options:NSDataReadingUncached error:&error];
UIImage * image=[UIImage imageWithData:data ];
[data release];
return image;
}
maybe I misunderstood your question, but from what you said, what you really want is to "serialise" the threads, that is, ensure they are executed one after the other. If this is the case I do not see a big advantage in having five (or more) threads if they spend most of the time waiting in a sort of "thread queue" :)
My 2 cents: Instead of playing with the threads' priority, maybe you should think about re-design the code to have a queue of files/images to load and a thread that dequeue and load the images one after the other. (the classic consumer/producer scenario)
If you need to speed up things you might think to have another thread doing some pre-fetching (if that make sense in your sw design/architecture)
CiaoCiao
Sergio
Sergio is right - if you can look at GCD and serialized queues, it shouldn't be too hard to migrate to it. Take a look at the videos from Apple for good how-to steps.

Memory leak that appears to be in touchJSON

Here's a leak problem that I'm having trouble with. Most of this code is just here for context so you can see that the "response" NSData object is not what's leaking.
If I drill down into the touchJSON code, following the stack trace as given to me by the LEAKS tool, the leak apparently begins life at the line
*outStringConstant ....
But since this is such a commonly used library, I doubt it's the problem.
One note. This doesn't leak the first time it's executed, only every subsequent time. But it leaks a lot, so the response data is probably the actual data that's leaking.
Also, if anyone is familiar with touchJSON and this code, can you explain to me what this outStringConstant variable is and what it does? It doesn't appear to play any role, other than to be assigned a copy of theString, though if I remove that line the code crashes.
MY CODE is
dataRequestURL = [NSString stringWithFormat:#"http://www....", ...];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:dataRequestURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:&ts_response error:&ts_error];
NSArray *array = [[CJSONDeserializer deserializer] deserialize:response error:nil]; <- LEAKS HERE
TOUCHJSON CODE is
-(BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)outError {
NSMutableString *theString = [[NSMutableString alloc] init];
if (outStringConstant != NULL) { *outStringConstant = [[theString copy] autorelease]; }
[theString release];
}

Resources