Hamdi-Lachaal
Hamdi-Lachaal

Reputation: 151

working with NSRunLoop

i'm running 2 methods in the viewDidLoad and between them im running NSRunLoop for 10 sec

-(void)nextImage{ //charging a random image in the image view

    index = [[NSArray alloc]initWithObjects:@"1.jpg",@"2.jpg",@"3.jpg",@"4.jpg",@"5.jpg",nil];
    NSUInteger randomIndex = arc4random() % [index count];
    NSString *imageName = [index objectAtIndex:randomIndex];
    NSLog(@"%@",imageName);
    self.banner=[UIImage imageNamed:imageName];
    self.imageView.image=banner;
    [imageName release];
}

-(void)horror{

    self.banner=[UIImage imageNamed:@"Flo.jpg"];
    self.imageView.image=banner;
    NSString *path = [NSString stringWithFormat:@"%@%@",[[NSBundle mainBundle] resourcePath],@"/scream.wav"];
    SystemSoundID soundID;
    NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
    AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
    AudioServicesPlaySystemSound(soundID);

}

- (void)viewDidLoad
{

    [self nextImage];

    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]];

    [self horror];

    [super viewDidLoad];
}

here the image don't change,black screen and after 10 sec i see only the result of [horror]. On the other side when i keep only [nextImage] in the viewDidLoad the image change, i think that something going wrong with my NSRunLoop

Upvotes: 0

Views: 799

Answers (1)

Dirk
Dirk

Reputation: 31061

You should not work with the run-loop directly most of the time. The method runUntilDate: does not, what you think it does. For your use case, you should set-up a timer:

- (void)viewDidLoad
{
    [self nextImage];
    [NSTimer scheduledTimerWithTimeInterval: 10.0 target: self selector: @selector(horror) userInfo: nil repeats: NO];
    [super viewDidLoad];
}

The timer will fire after 10 seconds (timeInterval: 10.0) and then make the target object (your view controller in this case due to target: self) perform the method horror (due to selector: @selector(horror)).

If there is any chance, that your view controller could become inactive before the time is elapsed, safe the timer instance in an ivar, and cancel it:

...
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 10.0 target: self selector: @selector(horror) userInfo: nil repeats: NO];
self.myTimerProperty = timer;
...

and when you need to cancel it:

...
if (self.myTimerProperty)
{
    // Ok. Since we have a timer here, we must assume, that we have set it
    // up but it did not fire until now. So, cancel it 
    [self.myTimerProperty invalidate];
    self.myTimerProperty = nil;
}
...

BTW, if you are doing this, it would probably a good idea to clear the timer property from within the callback method:

- (void) horror
{
    self.myTimerProperty = nil;
    ... other horrible stuff ...
}

Upvotes: 1

Related Questions