mehmeet43
mehmeet43

Reputation: 183

CustomDelegate on viewDidLoad

I'm calling a method which belongs to custom delegate class on viewDidLoad but it starts from [sampleProtocol startSampleProcess], starts from sleep(5), before it show me view controller and label1.

CustomDelegate *sampleProtocol = [[CustomDelegate alloc]init];
sampleProtocol.delegate = self;
[self.label1 setText:@"Processing..."];
[sampleProtocol startSampleProcess];

startSampleProcess method is below;

-(void)startSampleProcess{

    sleep(5);

    [self.delegate processCompleted];
}

processCompleted method is also below;

-(void)processCompleted{
    [self.label1 setText:@"Process Completed"];
}

It just set a label on viewcontroller, go to another class and do something simple (etc: sleep) and come back to view controller and set label again. I didn't try custom delegate before so it would be great if you help me on what I'm missing.

Upvotes: 0

Views: 52

Answers (1)

NobodyNada
NobodyNada

Reputation: 7634

The problem is that you are calling sleep on the main thread.

Here's how an iOS app works:

  1. Wait until something interesting happens.

  2. Process it.

  3. Go back to step 1.

The app has something called a runloop that receives messages from the system about touches, timers, etc. Every time it gets a message, it runs some code, often provided by you. When you call the sleep function, it suspends the current thread. When the thread is suspended, the run loop can't process new events until the sleep is done.

When you change something onscreen, you add an event to the run loop that says the screen needs to be redrawn. So, this is what is happening in your application:

  1. You change the label text. A redraw event is now added to the runloop.

  2. You sleep for 5 seconds, meaning the runloop can't process new events.

  3. 5 seconds later, the thread wakes up and changes the label's text.

  4. Control finally gets back to the run loop.

  5. The run loop processes the redraw event, changing the label's text.

If the task needs to be a long-running task, you can do it in a background thread:

-(void)startSampleProcess {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_NORMAL, 0) ^{  //run this code in the background so it doesn't block the runloop
        sleep(5);
        dispatch_async(dispatch_get_main_thread(), ^{    //after the task is done, call the delegate function back on the main thread since UI updates need to be done on the main thread
            [self.delegate processCompleted];
        });
    });
}

Upvotes: 1

Related Questions