ipad subview not loading before code is executing - iphone

I have a command that should be loading a subview before a particular piece of time intensive code executes. However the command runs, the timely code executes and then the subview shows up. Is there anything I can do to fix this problem?
progressViewController = [[ProgressView alloc] initWithNibName:#"ProgressView" bundle:[NSBundle mainBundle]];
[self.view addSubview:[progressViewController view]];
NSString *name=#"guy";
NSString *encodedName =[[NSString alloc] init];
int asci;
for(int i=0; i < [name length]; i++)
{
//NSLog(#"1");
asci = [name characterAtIndex:i];
NSString *str = [NSString stringWithFormat:#"%d,", asci];
encodedName =[encodedName stringByAppendingFormat: str];
}
NSString *urlString = [NSString stringWithFormat:#"someurl.com"];
NSURL *theUrl = [[NSURL alloc] initWithString:urlString];
NSString *result=[NSString stringWithContentsOfURL:theUrl];
result = [result substringFromIndex:61];
result = [result substringToIndex:[result length] - 20];
NSLog(result);
outLab.text=result;
[[progressViewController view] removeFromSuperview];

1) try
[self.view setNeedsUpdating]
after adding the subview
2)
try splitting the time intensive into another thread....
- (void) f
{
// executed in main UI thread
progressViewController = [[ProgressView alloc] initWithNibName:#"ProgressView" bundle:[NSBundle mainBundle]];
[self.view addSubview:[progressViewController view]];
[NSThread detachNewThreadSelector:#selector(doCompute) toTarget:self
withObject:nil];
}
- (void) doCompute
{
// in a different thread....so we need a autoreleasepool
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
// do your computation here...
[self performSelectorOnMainThread:#selector(taskComplete:)
withObject:result waitUntilDone:NO];
[autoreleasepool release];
}
- (void) taskComplete
{
// executed in UI thread
[self.progressView removeFromSuperView];
}

You could subclass the view and then use the viewDidLoad function to execute your long running code.

Related

iPhone -trouble with a loading data from webservice into a tableview

I am using a Window based application and then loading up my initial navigationview based controller in the appDelegate part - application didFinishLaunchingwithOptions (UPDATED)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
The method of getting the data from the webservice is usually triggered in this method of viewdidload .... in the [self getData]; method.
- (void)viewDidLoad
{
[super viewDidLoad];
if (_refreshHeaderView == nil) {
EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
view.delegate = self;
[self.tableView addSubview:view];
_refreshHeaderView = view;
[view release];
}
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
[self loadImages];
HUDMB = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUDMB];
HUDMB.dimBackground = YES;
// Regiser for HUD callbacks so we can remove it from the window at the right time
HUDMB.delegate = self;
HUDMB.labelText = #"Loading..";
[HUDMB show:TRUE];
[self getData];
[self.tableView reloadData];
}
Before loading it if the user is not registered/ does not have a credentials present then it takes the user to a login view controller .
- (void)loadView {
[super loadView];
if([Preferences isValid]?YES:NO)
{
}
else
{
int r = arc4random() % 5;
switch (r) {
case 0:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 1:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 2:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 4:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 3:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
default:
break;
}
}
}
I think the getdata function is making a lot of troubles. so let me add that and also the corresponding functions i use for data retrieval and serialization.
-(void)getData{
NSLog(#"loggin into call sheet page");
[self getCallSheetData];
NSLog(#"after call sheet");
}
- (void)getCallSheetData
{
NSString *postCMD = #"Blah... Blah... Blah...";
NSMutableData *postDataCMD = (NSMutableData *)[postCMD dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSURL *url = [NSURL URLWithString:[Preferences getURL]];
// NSLog(#"get call Sheet");
NSString *postLengthCMD = [NSString stringWithFormat:#"%d", [postDataCMD length]+1];
// NSLog(#"The CS String: %#",[Preferences retriveSession]);
requestCMD = [ASIHTTPRequest requestWithURL:url];
[requestCMD setURL:url];
[requestCMD addRequestHeader:#"Content-Length" value:postLengthCMD];
[requestCMD addRequestHeader:#"Content-Type" value:#"application/x-www-form-urlencoded"];
[requestCMD addRequestHeader:#"user-Agent" value:#"Mobile 1.4" ];
[requestCMD addRequestHeader:#"Content-Language" value:#"en-US"];
[requestCMD addRequestHeader:#"Accept-Encoding" value:#"gzip"];
[requestCMD addRequestHeader:#"Cookie" value:[Preferences retriveSession]];
[requestCMD setPostBody:postDataCMD];
[requestCMD setDelegate:self];
[requestCMD startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSMutableArray *CSArray = [[NSMutableArray alloc] init];
if( [[request responseString] isEqualToString:#"OK"]){
return;
}
// Use when fetching binary data
NSData *responseData = [request responseData];
NSDateFormatter *formatter1=[[NSDateFormatter alloc]init];
[formatter1 setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[formatter1 setTimeZone:gmt];
NSDateFormatter *formatterFinal=[[NSDateFormatter alloc]init];
[formatterFinal setDateStyle:NSDateFormatterMediumStyle];
[formatterFinal setTimeStyle: NSDateFormatterShortStyle];
[formatterFinal setLocale:[NSLocale currentLocale]];
JSONDecoder *jCSArray = [[JSONDecoder alloc]init];
NSMutableArray *theObject = [jCSArray objectWithData:responseData];
// CallSheet= [NSMutableArray arrayWithCapacity:50];
for(id key in theObject)
{
csr = [[CallSheetRecord alloc] init];
// cName,cCompany,cId,cMemberId,crcStatus,crcTarget,cImportance,cLastContact
csr.importance = #"1";
csr.rcstatus = #"1";
csr.rcTarget = #"1";
csr.company = #"";
csr.lastContact= #"";
if([key valueForKey:#"firstName"] != Nil)
{
csr.name = [NSString stringWithFormat:#"%#",[key valueForKey:#"firstName"]] ;
if ([key valueForKey:#"lastName"] != Nil) {
csr.name = [csr.name stringByAppendingString:#" "];
csr.name = [csr.name stringByAppendingString:[NSString stringWithFormat:#"%#",[key valueForKey:#"lastName"]]];
}
}
if([key valueForKey:#"company"] != Nil)
{
csr.company = [NSString stringWithFormat:#"%#",[key valueForKey:#"company"]] ;
}
if([key valueForKey:#"memberId"] != Nil)
{
csr.memberId = [NSString stringWithFormat:#"%#",[key valueForKey:#"memberId"]] ;
}
if([key valueForKey:#"id"] != Nil)
{
csr.id_ = [NSString stringWithFormat:#"%#",[key valueForKey:#"id"]] ;
}
if([key valueForKey:#"lastContact"] != Nil)
{
NSDate *finalDate =[formatter1 dateFromString:[NSString stringWithFormat:#"%#",[key valueForKey:#"lastContact"]]];
//NSString *timeStamp = [formatter1 stringFromDate:[finalDate descriptionWithLocale:[NSLocale currentLocale]]];
//NSLog(#"Time stamp : %#",[finalDate descriptionWithLocale:[NSLocale currentLocale]]);
//NSLog(#"Time stamp : %#",timeStamp);
//csr.lastContact = [key valueForKey:#"lastContact"];
csr.lastContact = [formatterFinal stringFromDate:finalDate];
}
if([key valueForKey:#"importance"] != Nil)
{
csr.importance = [NSString stringWithFormat:#"%#",[key valueForKey:#"importance"]];
}
if([key valueForKey:#"rcStatus"] != Nil)
{
csr.rcstatus= [NSString stringWithFormat:#"%#",[key valueForKey:#"rcStatus"]] ;
}
if([key valueForKey:#"rcTarget"] != Nil)
{
csr.rcTarget = [NSString stringWithFormat:#"%#",[key valueForKey:#"rcTarget"]] ;
}
[CSArray addObject:csr];
}
CSD = [CSArray mutableCopy];
[CSArray release];
[formatter1 release];
[formatterFinal release];
//CallSheetArray = [CSArray mutableCopy];
//[csr release];
[jCSArray release];
[HUDMB hide:TRUE];
[self.tableView reloadData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
UIAlertView *message = [[[UIAlertView alloc] initWithTitle:#"Hello World!"
message:[NSString stringWithFormat:#"%#",error]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil]autorelease];
[message show];
}
then right after that i try to load the table with [self getData]; that i get make using webservice call using asiHTTP .. for this question lets say it takes 3 seconds time to get the data and then deserialize it . now... my question is it works out okey in the later runs as I store the username and password in a seure location... but in the first instance.... i am not able to get the data to laod to the tableview... I have tried a lot of things...
1. Initially the data fetch methods was in a diffrent methods.. so i thought that might be the problem as then moved it the same place as the tbleviewController(navigationController)
2. I event put in the Reload data at the end of the functionality for the data parsing and deserialization... nothing happens.
3. The screen is black screen with nothing displayed on it for a good 5 seconds in the consecutive launches of the app.... so could we have something like a MBPorgressHUD implemented for the same.
could any one please help for these scenarios and guidance as to what paths to take from here. ...
Update:
Bounty Just answer 2 of the questions the best you can... The property was a thing i tried but it did not work... but my problem is not that... my problem is my screen is not able to load data from a webservice after i login until i do the "pull to refresh". Next eventualy starting my app takes about 5 seconds to show the screen(till that it shows a black screen)... what is the best way to show the apps Blank screen to the End- user when they make it to the app. I dont want the user to think the app is not working or has adversly affected their phone.
There are a number of potential issues here. The first is related to [self getData] - is this blocking or not?
1. getData is blocking (synchronous)
If this method is blocking (i.e. does not return immediately) then this will explain why you are not seeing anything on the screen for a few seconds. You are currently calling this method in the main thread, so it will stop the UI from being updated until is complete.
You can make it run in the background by doing this:
- (void) getDataInBackgroundThread
{
NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
[self getData];
// force the table to redraw - UI operations must be on the main thread
[tableView performSelectorOnMainThread:#selector( reloadData )];
[pool drain];
}
In your main code, now instead of calling [self getData] call [self getDataInBackgroundThread];
2. getData is not blocking (asynchronous)
Even if getData is blocking, if it runs in the main thread it will still cause the UI to hang. Also, if it uses a lot of processor time it will slow down the UI and give the appearance of not running in the background.
To address this issue, you would need make sure the lengthy operation of getData really is not running in the main thread and also put in sleep() calls every so often to give some time for the UI to update.
You still haven't given enough info for people to really help, we're just guessing.
It is highly likely the delay is caused by getData. Try commenting that out or bracket it with NSLog statements to verify.
You should show us more code, specifically what is happening in getData and any delegate or notification handling implementations related to loading data.
You don't need to explicitly call [tableView reloadData] in viewDidLoad. The tableView automatically loads data the first time it is displayed.
As #dmatt said, if you are loading data asynchronously then getData would return immediately with no delay. You would typically would either respond to delegate messages or notifications (depending on how you are loading data) to reload the table when the data is finished loading and serializing.
There are lots of folks on SO who are happy to try and help you if given enough info. Especially when you offer a bounty.

Can we thread the web-service and insert in in custom table cell?

The thing is i have to make Custom cell of UITable, i have to call large webservice with many data which will take longer tym to load it once. So i want to apply threading in it. now my que is. can we at run -time insert value one by one in custom cell , as user will see data comming one by one at run time..?? if yes how we can do that.
yes you can ... try this
- (void)viewDidLoad
{
myApp = (myAppDelegate *) [[UIApplication sharedApplication] delegate];
[self performSelectorInBackground:#selector(startParsing) withObject:nil];
[super viewDidLoad];
}
- (void) startParsing
{
[self performSelectorOnMainThread:#selector(startIndicator) withObject:nil waitUntilDone:NO];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [[NSURL alloc] initWithString:#"http://abc.com"];
NSData *data = [NSData dataWithContentsOfURL:url];
// 2 -- parsing
parser = [[VolMyParser alloc] init];
[parser parseXML:data];
[data release];
//[parser print];
[self performSelectorOnMainThread:#selector(updateTable) withObject:nil waitUntilDone:NO];
[pool release];
}
- (void) startIndicator
{
av.hidesWhenStopped = YES;
[av startAnimating];
}
- (void) updateTable
{
[av stopAnimating];
[myTable reloadData];
}
Hope its gives you an Idea...

Image view not updating on NSThread

I'm trying to make a test app which measures the performance for threads. However, I'm trying to set an image to imageview on a thread and it's not updating. In fact, the methods setImage1 and setImage2 aren't even getting called. Any ideas?
Look at the code for details
#import "UntitledAppDelegate.h"
#import <QuartzCore/QuartzCore.h>
#implementation UntitledAppDelegate
#synthesize window, imageView1, imageView2, label1, label2, label0;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[window makeKeyAndVisible];
return YES;
}
-(IBAction) startSeparate:(id) sender
{
imageView1.image = imageView2.image = nil;
double prev;
start = prev = CACurrentMediaTime();
[self setImage1];
label1.text = [NSString stringWithFormat:#"%.10g", CACurrentMediaTime() - prev];
prev = CACurrentMediaTime();
[self setImage2];
label2.text = [NSString stringWithFormat:#"%.10g", CACurrentMediaTime() - prev];
}
-(IBAction) startThreaded:(id) sender
{
imageView1.image = imageView2.image = nil;
double prev;
NSThread *t1 = [[NSThread alloc] init];
[t1 start];
NSThread *t2 = [[NSThread alloc] init];
[t2 start];
start = prev = CACurrentMediaTime();
//This doesn't work
//[self performSelector:#selector(setImage1) onThread:t1 withObject:nil waitUntilDone:NO];
//But this does
[self performSelectorInBackground:#selector(setImage1) withObject:nil];
label1.text = [NSString stringWithFormat:#"%.10g", CACurrentMediaTime() - prev];
prev = CACurrentMediaTime();
//This doesn't work
//[self performSelector:#selector(setImage2) onThread:t2 withObject:nil waitUntilDone:NO];
//But this does
[self performSelectorInBackground:#selector(setImage2) withObject:nil];
label2.text = [NSString stringWithFormat:#"%.10g", CACurrentMediaTime() - prev];
}
-(void) setImage1
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *image1 = [UIImage imageNamed:#"bird.png"];
imageView1.image = image1;
[self pictureDone];
[pool drain];
}
-(void) setImage2
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *image2 = [UIImage imageNamed:#"bird.png"];
imageView2.image = image2;
[self pictureDone];
[pool drain];
}
-(void) pictureDone
{
done++;
NSLog(#"%i", done);
if (done == 2) {
label0.text = [NSString stringWithFormat:#"%.10g", CACurrentMediaTime() - start];
done = 0;
}
}
#end
Never change anything in a currently displayed UIView from a background thread. There are a million different synchronization problems that you can encounter. Download the image in the background thread, and then call another method on the main thread (from the background thread) to actually update the UIImageView
performSelectorOnMainThread:...
As for the problem with the method not running, try this instead:
[self performSelectorInBackground:#selector(setImage2:) withObject:nil];
(adding a colon after setImage2).
Also, I don't think those two NSThread objects (t1 and t2) are necessary, and they are also probably creating a memory leak.
Technically, NSThread itself do not create run loop automatically, then the performSelector:onThread won't work if you just create thread that way.

giving nil while accessing the nsmutable array

i am parsing a json object and storing the song objects in songs, a nsmutable array.
while am displaying the image of the song i.e. while accessing the object from the array its giving all values nil in that object.
in the following code in setSongsScrollView method, in for loop while accessing the song object from songs array its showing nill in the debugger and crashing with error EXEBadacess.But the count of that array is giving correct.
can any body help me out please
- (void)viewWillAppear:(BOOL)animated{
[super viewDidLoad];
[self parsingTheStation];
[self load_images];
[self setSongsScrollView];
}
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
- (void)parsingTheStation{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http:...."]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *jsonString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSDictionary *dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];
songs =[[NSMutableArray alloc]init];
NSArray *songObjects = [dictionary objectForKey:#"songs"];
for(NSDictionary *s in songObjects){
aSong = [[Song alloc] init];
aSong.artist = [s objectForKey:#"by"];
aSong.genre = [s objectForKey:#"genre"];
aSong.cover = [s objectForKey:#"cover"];
aSong.song_id = [s objectForKey:#"id"];
aSong.rank = [s objectForKey:#"rank"];
aSong.title = [s objectForKey:#"title"];
aSong.link = [s objectForKey:#"link"];
[songs addObject:aSong];
[aSong release];
}
NSLog(#"total number of songs is : %d",[songs count]);
}
-(void)setSongsScrollView {
songsContainer = [[UIScrollView alloc]init];
int songsCount = [self.songs count];
//totla no. of songs we get +4
int tSongs = songsCount+4;
int n = sqrt(tSongs);
int p = n,q = n;
int remSongs = tSongs-(n*n);
if(remSongs >= n){
q = q+(remSongs/n);
if((remSongs%n)>0)
q++;
}else q++;
for(int i=0;q>p;i++){
q--;
p++;
}
NSLog(#"total songs..%d",tSongs);
NSLog(#"total rows..%d",q);
NSLog(#"total columns..%d",p);
songsContainer.contentSize = CGSizeMake(120*q, 120*p);
int x =0, y=240, col=1;
for(int i=0;i<songsCount;i++){
CGRect imgFrame = CGRectMake(x, y, 118, 118);
NSLog(#"songs conunt ...%d",[songs count]);
Song *thesong = [[Song alloc]init];
thesong = [self.songs objectAtIndex:i];
NSString *filename = [NSString stringWithFormat:#"%#/%#", [LazyImageView dataPath], [thesong.cover lastPathComponent]];
UIImageView *tempImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filename]];
tempImg.tag = i;
tempImg.frame = imgFrame;
[songsContainer addSubview:tempImg];
[tempImg release];
[thesong release];
y += 120;
if(y>=(120*p)){
NSLog(#"total y..%d",y);
col++;
x += 120;
if(col>=3)
y=0;
else
y=240;
}
}
NSLog(#"total y..%d",y);
NSLog(#"content size..%d,%d",120*q,120*p);
}
-(void)load_images{
for(int i=0;i<[songs count];i++){
Song *rsong = [[Song alloc]init];
rsong = [self.songs objectAtIndex:i];
lazyBigImg = [[LazyImageView alloc] init];
NSURL* url = [NSURL URLWithString:rsong.cover];
[lazyBigImg loadImageFromURL:url];
[lazyBigImg release];
[rsong release];
}
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[songs release];
[lazyBigImg release];
[onAirBtn release];
[chartsBtn release];
[dealsBtn release];
[searchBtn release];
[stNameLbl release];
[aSong release];
[songsContainer release];
[super dealloc];
}
#end
Marcel has basically got the right answer but I think a little more explanation is needed. Look at the following lines from setSongsScrollView:
Song *thesong = [[Song alloc]init];
The above line allocates a new Song that you own and assigns a reference to it to thesong
thesong = [self.songs objectAtIndex:i];
The above line replaces that reference with a new reference to a song from the array that you don't own. Remember that: you do not own the song referenced by thesong now. There are now no more references left to the object you just allocated, but you still own it. The object has therefore leaked.
NSString *filename = [NSString stringWithFormat:#"%#/%#", [LazyImageView dataPath], [thesong.cover lastPathComponent]];
Use stringByAppendingPathComponent: to build file paths, not stringWithFormat:.
UIImageView *tempImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:filename]];
tempImg.tag = i;
tempImg.frame = imgFrame;
[songsContainer addSubview:tempImg];
[tempImg release];
[thesong release];
The last line in the above sequence releases the object referenced by thesong. As noted above, you do not own that object. You must not release it, but you have anyway. This means that, at some point, may be now, maybe later, the object will be deallocated while something (probably the array) still thinks it has a valid reference. That's what causes the crash.
-(void)load_images{
for(int i=0;i<[songs count];i++){
Song *rsong = [[Song alloc]init];
rsong = [self.songs objectAtIndex:i];
lazyBigImg = [[LazyImageView alloc] init];
NSURL* url = [NSURL URLWithString:rsong.cover];
[lazyBigImg loadImageFromURL:url];
[lazyBigImg release];
[rsong release];
}
}
The above method contains exactly the same error.
You're creating a new Song instance (thesong), then assign this very instance to a song presumably already in the array. That makes no sense at all and is probably responsible for the memory error.
You shouldn't need to be creating new Songs if they are already in the array. Instead:
Song *thesong = [self.songs objectAtIndex:i];
Also look into using the Objective-C 2.0 for-each loop syntax.

xml parsing consumes time need efficent way on iphone

How to call main thread ??? i can parse but i cant display data
- (void)viewDidLoad {
//self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"10.png"]];
[super viewDidLoad];
[NSThread detachNewThreadSelector:#selector(startTheBackgroundJob) toTarget:self withObject:nil];
}
- (void)startTheBackgroundJob {
NSUserDefaults *getida = [NSUserDefaults standardUserDefaults];
myIDa = [getida stringForKey:#"AppID"];
NSLog(#"#BOOK MARK ");
NSString *ubook = [[NSString alloc] initWithFormat:#"http://www.wapp=%#&action=show",myIDa];
NSLog(#" bookmark %#",ubook);
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//NSString *outputString = [[NSString stringWithString:usearch] stringByAppendingString: UserText];
ubook = [ubook stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"My string is now = %#", ubook);
NSURL *url = [[[NSURL alloc] initWithString:ubook]autorelease];
//NSURL *url= [NSURL URLWithString:outputString];
NSLog(#" bookmark URL IS %#",url);
NSXMLParser *xmlParser = [[[NSXMLParser alloc] initWithContentsOfURL:url] autorelease];
//Initialize the delegate.
XMLParserbookm *parser = [[[XMLParserbookm alloc] initXMLParser]autorelease];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{
NSLog(#" xml parsed suucess");
//[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
//[self searchTableView];
//mytimer4=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(wipe) userInfo:nil repeats:NO];
}
else{
NSLog(#"eeror");
}
[NSThread sleepForTimeInterval:3];
[self performSelectorOnMainThread:#selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO]; // HOW TO CALL MAIN THREAD
[pool release]
}
You can try with
viewDidAppear:, this method is called after you go to a new view. Then at least, you can switch to new view, you should make sure that there is something on the screen in waiting for the xml parsing
Using Thread: You put parsing into another thread and then callback your main thread after you finish, then there will be no block at all