NSTimer and UIView Memory Mistake - objective-c

i create views and release all objects. i used NSTimer and
//at viewdidload
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 15.0
target: self
selector:#selector(selectorSwitcher:)
userInfo: nil repeats:YES];
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:timer forMode: NSDefaultRunLoopMode];
-(void)selectorSwitcher:(NSTimer *)timer {
[self viewDidLoad];
}
but myviews can not delete from scrollview. Creating a more views up to others. How can i resolve this problem?
Thanks
if (tempView.frame.origin.x > createview.frame.size.width) {
tempLabel = [[UILabel alloc] initWithFrame:CGRectMake((lblname_marginleft + (i * widthOfView))-((i/sutun)*mview_width), lblname_margintop + ((i/sutun) * heightOfView), labelwidth, labelheight)];
tempNumber = [[UILabel alloc] initWithFrame:CGRectMake((lblnumber_marginleft + (i* widthOfView))-((i/sutun)*mview_width), lblnumber_margintop + ((i/sutun) * heightOfView), labelwidth, labelheight)];
tempyuzde= [[UILabel alloc] initWithFrame:CGRectMake((15 + (i*widthOfView))-((i/sutun)*mview_width), 10 + ((i/sutun) * heightOfView), labelwidth, labelheight)];
tempView = [[UIView alloc] initWithFrame:CGRectMake((10 + (i* widthOfView)) - ((i/sutun)*mview_width), ((i/sutun) * heightOfView), widthOfView, heightOfView)];

You should not be calling viewDidLoad - the system calls it once the view has loaded. To load the view, simply do:
UIView *view = self.view;
Calling self.view implicitly loads the XIB file. However the system also loads the view automatically when it is time to do so - what functionality are you trying to achieve?
Also, you should not be calling
NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:timer forMode: NSDefaultRunLoopMode];
Since by calling scheduledTimerWithTimeInterval... you've already scheduled the timer - you don't need to schedule it again.

Related

How to remove subclass of UILabel in itself

A subclass of UILabel called NewLabel, in NewLabel.m
+ (NewLabel*)addLabelIntoView:(UIView*)view
{
NewLabel *label = [[NewLabel alloc] init];
CGSize size = CGSizeMake(120.0f, 40.0f);
CGPoint point = CGPointMake(view.bounds.size.width / 2, view.bounds.size.height / 2);
label.frame = CGRectMake(0, 0, size.width, size.height);
label.center = point;
[view addSubview:label];
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(removeLabelFromView) userInfo:nil repeats:NO];
return label;
}
- (void)removeLabelFromView {
[self removeFromSuperview];
}
and in a UIViewController.m, I add this for showing the NewLabel, and close itself
[NewLabel addLabelIntoView:self.view]
but it always crash, here is crash info
+[NewLabel removeLabelFromView]: unrecognized selector sent to class 0x103d40738
Any ideas?
In a class method is self the class. Instead of +[NewLabel removeLabelFromView] you probably want to do -[NewLabel removeLabelFromView]. Change
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(removeLabelFromView) userInfo:nil repeats:NO];
to
[NSTimer scheduledTimerWithTimeInterval:1.0f target:label selector:#selector(removeLabelFromView) userInfo:nil repeats:NO];

Display an image for 1 sec on the view

What I want to realize is:
When I touch a button, the image display on the view for 1 sec, then the image disappear.
I know that a NSTimer will help, but i dont know how to write the right code...need your help, thanks.
- (IBAction)bodytouched:(id)sender {
bodytouchedimage.hidden = NO;
bodytouchedimage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"beated.jpg"]];
bodytouchedimage.userInteractionEnabled = YES;
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(showPictures:) userInfo:nil repeats:NO];
}
- (void)showPictures:(NSTimer *)timer {
bodytouchedimage.hidden = YES;
}
What you should to is call the showPictures function when you touch the button and then within the showPictures method you add a NSTimer that will call a hidePictures method 1 second later
- (void)showPictures
{
bodytouchedimage.hidden = NO;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(hidePictures) userInfo:nil repeats:NO];
}
- (void)hidePictures
{
bodytouchedimage.hidden = YES;
}
Rather than using NSTimer, it would be easier to simply call your method to hide the image like this:
- (IBAction)bodytouched:(id)sender {
bodytouchedimage.hidden = NO;
bodytouchedimage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"beated.jpg"]];
bodytouchedimage.userInteractionEnabled = YES;
[self performSelector:#selector(hidePicture) withObject:nil afterDelay:1];
}
- (void)hidePicture {
bodytouchedimage.hidden = YES;
}
performSelector:withObject:afterDelay: is a method of the NSObject class.

Objective C: Passing variables between classes

I want to pass an NSMutableDictionary from one class through a timer to another class that is called from the timer. I get an error at #selector([generateStickFig:enemies]) I've tried taking [] out but it still errs.
-(void)awakeFromNib {
//start timer that fires every second
NSMutableDictionary *enemies = [[NSMutableDictionary alloc] init];
[NSTimer scheduledTimerWithTimeInterval:(0.001) target:self selector:#selector([generateStickFig:enemies]) userInfo:nil repeats:YES];
}
-(void) generateStickFig:(NSMutableDictionary *)enemies {
int x = random() % 1000;
if (x == 1) {
stickFig = [[UIButton alloc] initWithFrame:CGRectMake(0, 650, 50, 50)];
[stickFig setBackgroundColor:[UIColor blackColor]];
[stickFig addTarget:self action:#selector(tapFig:) forControlEvents:UIControlEventTouchUpInside];
[enemies setObject:object forKey:[NSString stringWithFormat:#"object%i",i]];
[self.view addSubview:stickFig];
}
}
Any suggestions?
Try
[NSTimer scheduledTimerWithTimeInterval:(0.001) target:self selector:#selector(generateStickFig:) userInfo:enemies repeats:YES];
to create the timer. Then change the callback method to
-(void) generateStickFig:(NSTimer *)timer {
NSDictionary *enemies = (NSDictionary *)timer.userInfo;
...
}

Objective-C help NSTimer doesn't repeat

i need a little help i have a method; countDown which is called when iTunes sends a notification, the method countDown then runs the method timerHit which gets a double minuses one from it then sets the value to a label, the method countDown is set to repeatedly run timerHit, however it doesn't seem to be working.
Here's what i have so far, any help would be much appreciated.
- (void)countDown {
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(timerHit:) userInfo:nil repeats:YES];
}
- (void)timerHit:(NSTimer *)p_timer {
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
if ([iTunes isRunning]) {
double trackDuration = [[iTunes currentTrack] duration];
trackDuration--;
[duration setDoubleValue:trackDuration];
}
}
Thanks, Sami.
If the timer is on a thread then you should run it on a active run loop like so:
NSRunLoop *mLoop = [NSRunLoop currentRunLoop];
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(timerHit:) userInfo:nil repeats:YES];
mRunLoop = YES;
while (mRunLoop && [mLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]);

Cocoa Touch - Looping Help

I need help with some programming logic... I need to loop this method to display the math problem in my labels then sleep(5) and then loop again. Anything I've tried ends of freezing the program. PLEASE help! I've been tearing my hair out trying everything I know!
EDIT: I edited the code to this, After 3 seconds it fades away the label displaying the problem but then it crashed and the debugger displays 2010-08-06 10:43:27.776 Reactor [13444:207] modifying layer that is being finalized - 0x5c13500
//quickfire problems
-(void)simpleMath{ //"Tap when the answer is X"
isTimeToTap = NO;
int problemSelector = arc4random() % 4;
NSArray *mathProblems = [[NSArray alloc] initWithObjects:#"6 - 1",#"2 + 3",#"3 x 2",#"3 x 1",#"2 x 4",nil]; //correct index 2
NSArray *mathAnswers = [[NSArray alloc] initWithObjects:#"5",#"5",#"6",#"3",#"8",nil]; //correct index 2
if ([mathAnswers objectAtIndex:problemSelector] == #"6") {
isTimeToTap = YES;
}
if (ranBefore == NO) { //create labels
//tell when to tap
tapTellerTop.text = #"Tap when the answer is 6!";
tapTellerBottom.text = #"Tap when the answer is 6!";
//make bottom label
mathDisplayBottom = [[UILabel alloc] initWithFrame:CGRectMake(15, 250, 242, 92)];
mathDisplayBottom.font = [UIFont fontWithName:#"Helvetica" size: 96.0];
mathDisplayBottom.textColor = [UIColor whiteColor];
mathDisplayBottom.backgroundColor = [UIColor clearColor];
[self.view addSubview: mathDisplayBottom];
//make top label
mathDisplayTop = [[UILabel alloc] initWithFrame:CGRectMake(55, 120, 242, 92)];
mathDisplayTop.font = [UIFont fontWithName:#"Helvetica" size: 96.0];
mathDisplayTop.textColor = [UIColor whiteColor];
mathDisplayTop.backgroundColor = [UIColor clearColor];
[self.view addSubview: mathDisplayTop];
//rotate top label
mathDisplayTop.transform = CGAffineTransformMakeRotation(180.0 /180.0 * M_PI);
}
//if ran before just update the text
mathDisplayBottom.text = [mathProblems objectAtIndex:problemSelector];
mathDisplayTop.text = [mathProblems objectAtIndex:problemSelector];
ranBefore = YES; //if its here. its been ran.
//run timer wait for (3) then loop again until userTaps = YES
[self performSelector:#selector(simpleMath) withObject:nil afterDelay:3.0f];
[mathProblems release];
[mathAnswers release];
[mathDisplayBottom release];
[mathDisplayTop release];
}
Sleep will stop your application from running or responding at all. Here is a quick partial example of a view controller you could use. This assumes you wire up the tap button and only uses one of the labels, etc. but you can play around with it. Also, this won't deal with memory issues or anything, so you'd add support for that.
But, once this view controller is created and the view installed, the math problem will update every 5 seconds. If the user presses the button and the answer is valid, we log a success message, otherwise we log fail message.
#interface myMathController : UIViewController {
NSArray* mathProblems;
NSIndexSet* validIndexes;
NSUInteger currentIndex;
NSTimer* timer;
}
#property(nonatomic,assign) IBOutlet UILabel* mathDisplayLabel;
- (void)updateProblem:(NSTimer*)timer;
- (IBAction)userTap;
#end
#implementation myMathController
- (void)viewDidLoad
{
[super viewDidLoad];
mathProblems = [[NSArray alloc] initWithObjects:#"6 - 1",#"2 + 3",#"3 x 2",#"3 x 1",#"2 x 4",nil];
// Add all valid answers
NSMutableIndexSet* tempIndexes = [[NSMutableIndexSet alloc] init];
[tempIndexes addIndex:2];
validIndexs = [tempIndexes copy];
[tempIndexes release];
timer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:5.0 target:self selector:#selector(updateProblem:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)updateProblem:(NSTimer*)timer
{
currentIndex = arc4random() % [mathProblems count];
[mathDisplayLabel setText:[mathProblems objectAtIndex:currentIndex]];
}
- (void)userTap
{
if( [validIndexes containsIndex:currentIndex] ) {
NSLog(#"This user is SMART!");
} else {
NSLog(#"This user needs more work!");
}
}
- (void)dealloc
{
[timer invalidate];
[timer release];
[mathProblems release];
[validIndexes release];
[super dealloc];
}
#end
You shouldn't sleep(), ever. To invoke a function repeatedly, call:
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(doStuff:)
userInfo:nil repeats:YES];
then define the function:
-(void)doStuff:(NSTimer*)timer
{
// stuff
if ( iAmDone ) [timer invalidate];
}
OR if you want to fire another call, after 5 seconds, you could call
if ( !iAmDone ) [self performSelector:#selector(simpleMath) afterDelay:5];
at the end of simpleMath.