Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 03-31-2009, 09:49 AM   #1 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 11
matsoftware is on a distinguished road
Unhappy Problems with UILabel and while loop

Hi everybody,

I'm currenlty developing a simple test software for iPhone that use only an UILabel and an UIButton. The button is linked to the "writeresult" action that contains the following code:

Code:
	while (i<1000)
	{	
		NSString *text = [[NSString alloc] initWithFormat: @"Number: %d", i];
		labelOutput.text = text;
		[text release];
		i++;
	}
with "labelOutput" declared in the class.h file as:

Code:
@property (nonatomic, retain) UILabel *labelOutput;
and @syntetize labelOutput; in class.m file.

The problem is that when the user tap the button, it will show only the last number. The label doesn't appear with the value increasing (i think, it doesn't "reload" its content) and the software seems like freezing during the cycle (no user interaction till the loop ending).

How to show updated text in the UILabel when "i" increase (ie: "Number: 1" then "Number: 2" .... etc) ?

Thanks :-)
matsoftware is offline   Reply With Quote
Old 03-31-2009, 10:05 AM   #2 (permalink)
Registered Member
 
Join Date: Jan 2009
Posts: 97
JoeBlaze is on a distinguished road
Default

Try this

Code:
while (i<1000)
	labelOutput.text = [labelOutput.text stringByAppendingFormat:@"Number: %d ", i++];
i++ will not be performed until after that line of code is executed so you should get your expected results
JoeBlaze is offline   Reply With Quote
Old 03-31-2009, 10:09 AM   #3 (permalink)
Dr. Touch Cocoa Helpdesk
iPhone Dev SDK Supporter
 
Join Date: Sep 2008
Location: Vienna, Austria
Posts: 537
Oliver Drobnik is on a distinguished road
Send a message via AIM to Oliver Drobnik Send a message via MSN to Oliver Drobnik Send a message via Skype™ to Oliver Drobnik
Default

Quote:
Originally Posted by JoeBlaze View Post
Try this

Code:
while (i<1000)
	labelOutput.text = [labelOutput.text stringByAppendingFormat:@"Number: %d ", i++];
i++ will not be performed until after that line of code is executed so you should get your expected results
Generally you have to allow your apps to get into the run loop for UI elements to be updated. Never write any functions that will take too long unless you do them with NSOperation or multithreaded.

A easy way around this is to do the updating in NSTimer method.
__________________
regards

Oliver Drobnik
Cocoanetics - Our DNA is programmed in Objective-C.

Linguan – makes localizing strings file fun!

Cocoanetics Parts Store – easy to use yet professionally looking components that you can use to spruce up your own apps. Augmented Reality, Calendar Control, Pin Lock or Purchase Button are only some examples. You get full source code, no static library crap, and lifetime support. Check it out today!
Oliver Drobnik is offline   Reply With Quote
Old 03-31-2009, 10:14 AM   #4 (permalink)
Registered Member
 
Join Date: Jan 2009
Posts: 97
JoeBlaze is on a distinguished road
Default

Yes Oliver is right, for some reason I thought you were trying to add onto the string. NSTimer seems like your best option because you probably want it to update the display at some set interval such as 1 second.
JoeBlaze is offline   Reply With Quote
Old 03-31-2009, 10:55 AM   #5 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 11
matsoftware is on a distinguished road
Default

Quote:
Originally Posted by Oliver Drobnik View Post
Generally you have to allow your apps to get into the run loop for UI elements to be updated. Never write any functions that will take too long unless you do them with NSOperation or multithreaded.

A easy way around this is to do the updating in NSTimer method.
You're right :-)

I've read the NSTimer description in the xcode documentation but I didn't understand how to use it .. I'm a newbie with objective - c :-P
matsoftware is offline   Reply With Quote
Old 04-01-2009, 02:22 AM   #6 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 11
matsoftware is on a distinguished road
Default

I tried with the following code:

Code:
	NSTimer *timer;
	timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(testFunction:) userInfo: nil repeats: YES];
before the "while" loop and then in the class.m file I wrote (out of the "writeresult" function) the following:

Code:
-(void)testFunction:(NSTimer*)timer {
	//
	fooLabel.text = @"Yes, timer activated!";
}
where fooLabel is a new UILabel with the same declaration of labelOutput.

But it doesn't behave how I would .. it shows the 999 number (the last "i" value) yet and the string in fooLabel AFTER the ending of the while loop..:-(
matsoftware is offline   Reply With Quote
Old 04-01-2009, 02:30 AM   #7 (permalink)
Dr. Touch Cocoa Helpdesk
iPhone Dev SDK Supporter
 
Join Date: Sep 2008
Location: Vienna, Austria
Posts: 537
Oliver Drobnik is on a distinguished road
Send a message via AIM to Oliver Drobnik Send a message via MSN to Oliver Drobnik Send a message via Skype™ to Oliver Drobnik
Default

Quote:
Originally Posted by matsoftware View Post
I tried with the following code:

Code:
	NSTimer *timer;
	timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(testFunction:) userInfo: nil repeats: YES];
before the "while" loop and then in the class.m file I wrote (out of the "writeresult" function) the following:

Code:
-(void)testFunction:(NSTimer*)timer {
	//
	fooLabel.text = @"Yes, timer activated!";
}
where fooLabel is a new UILabel with the same declaration of labelOutput.

But it doesn't behave how I would .. it shows the 999 number (the last "i" value) yet and the string in fooLabel AFTER the ending of the while loop..:-(

You also need to move the incrementing to the testFunction!
__________________
regards

Oliver Drobnik
Cocoanetics - Our DNA is programmed in Objective-C.

Linguan – makes localizing strings file fun!

Cocoanetics Parts Store – easy to use yet professionally looking components that you can use to spruce up your own apps. Augmented Reality, Calendar Control, Pin Lock or Purchase Button are only some examples. You get full source code, no static library crap, and lifetime support. Check it out today!
Oliver Drobnik is offline   Reply With Quote
Old 04-01-2009, 03:10 AM   #8 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 11
matsoftware is on a distinguished road
Default

Quote:
Originally Posted by Oliver Drobnik View Post
You also need to move the incrementing to the testFunction!
Do you mean put the "i++" in the testFunction?

I think I've some problems with the NSTimer.
To figure out with it I tried using the following:

Code:
- (IBAction)writeresult:(id)sender {
	
	NSTimer *timer;
	timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(testFunction:) userInfo: nil repeats: YES];
	
	[timer release];
	
}
and

Code:
-(void)testFunction:(NSTimer*)timer {

	NSLog(@"Timer activated");
}
but I receive this error in gdb:

Code:
MyTest(770,0xa06f2720) malloc: *** error for object 0x542e00: double free
*** set a breakpoint in malloc_error_break to debug
without any NSLog printed
matsoftware is offline   Reply With Quote
Old 04-01-2009, 03:16 AM   #9 (permalink)
Dr. Touch Cocoa Helpdesk
iPhone Dev SDK Supporter
 
Join Date: Sep 2008
Location: Vienna, Austria
Posts: 537
Oliver Drobnik is on a distinguished road
Send a message via AIM to Oliver Drobnik Send a message via MSN to Oliver Drobnik Send a message via Skype™ to Oliver Drobnik
Default

[quote=matsoftware;67763]Do you mean put the "i++" in the testFunction?


Code:
	[timer release];
UAAAAA. Don't release stuff that you don't own!! Only release objects that you yourself have instantiated with alloc/init.

The scheduleTimer... method is autoreleased at the end of the function and if you have an additional release you get a double release crash.

Yes, the increment and setting of the label has to go into the timer function.
__________________
regards

Oliver Drobnik
Cocoanetics - Our DNA is programmed in Objective-C.

Linguan – makes localizing strings file fun!

Cocoanetics Parts Store – easy to use yet professionally looking components that you can use to spruce up your own apps. Augmented Reality, Calendar Control, Pin Lock or Purchase Button are only some examples. You get full source code, no static library crap, and lifetime support. Check it out today!
Oliver Drobnik is offline   Reply With Quote
Old 04-01-2009, 03:42 AM   #10 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 11
matsoftware is on a distinguished road
Default

Mea culpa, mea culpa, mea grandissima culpa!

Thank you very much!!
I figured out by removing the [timer release] and by putting in testFunction the following code:

Code:
		NSString *text = [[NSString alloc] initWithFormat: @"Number: %d", i];
		labelOutput.text = text;
		[text release];
		i++;

if (i == 1000) [timer invalidate];
and it works :-) Again thank you!
matsoftware is offline   Reply With Quote
Old 03-30-2011, 01:13 AM   #11 (permalink)
Registered Member
 
Join Date: Mar 2011
Posts: 5
Vitamblu is on a distinguished road
Default

Quote:
Originally Posted by matsoftware View Post
Mea culpa, mea culpa, mea grandissima culpa!

Thank you very much!!
I figured out by removing the [timer release] and by putting in testFunction the following code:

Code:
		NSString *text = [[NSString alloc] initWithFormat: @"Number: %d", i];
		labelOutput.text = text;
		[text release];
		i++;

if (i == 1000) [timer invalidate];
and it works :-) Again thank you!
is that code you put in the testFunction within the while loop? Could you provide the whole tesFunction code, I couldn't figure out how you get it to work. I probably misunderstood somewhere.

I tried the following:
Code:
-(void)testFunction:(NSTimer*)timer
{
    NSLog(@"Timer activated");

    int i = 0;
    while (i<1000) {
        NSString *text = [[NSString alloc] initWithFormat: @"Number: %d", i];
        _labelOutput.text = text;
        [text release];
        i++;
        
    
        if (i == 1000)
        {
            [timer invalidate];
        }
    }
}

-(void)writeResult:(id)sender
{   
    NSTimer *timer;
	timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(testFunction:) userInfo: nil repeats: YES];
}
Vitamblu is offline   Reply With Quote
Reply

Bookmarks

Tags
loop, uilabel

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 330
5 members and 325 guests
blueorb, guusleijsten, Kryckter, LEARN2MAKE, SLIC
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,649
Threads: 94,113
Posts: 402,880
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Anwerbl
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 08:53 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0