5

I have implemented the following NSOperation, to draw N custom views

- (void)main {

    for (int i=0; i<N; i++) {

       << Alloc and configure customView #i >>
       //(customView is a UIView with some drawing code in drawrect)

       [delegate.view addSubview:customView];

    }

    NSLog(@"Operation completed");
}

in the drawRect method of the customView I have

- (void)drawRect {

    <<Drawing code>>

    NSLog(@"Drawed");
    delegate.drawedViews++;

    if (delegate.drawedViews==VIEWS_NUMBER) {
        [delegate allViewsDrawn];
    }
}

So the delegate get the notification when all the views are drawn.

The problem is that after the "Operation completed" log it takes about 5 seconds before I can see the first "Drawed" log.

Why is this happening? And generally speaking, how should I behave in order to find out which line of code is taking so much time being executed?

------ EDIT ------

Sometimes (like 1 out of 10 times) I was getting crashes doing this because I shouldn't call addsubview from the NSOperation since it is not thread-safe. So I changed it to:

[delegate.view  performSelectorOnMainThread:@selector(addSubview:) withObject:customView waitUntilDone:NO];

Now I don't have crashes anymore, but the process takes a very long time to be executed! Like 5 times more than before.

Why is it so slow?

Piotr Niewinski
  • 1,298
  • 2
  • 15
  • 27
Abramodj
  • 5,709
  • 9
  • 49
  • 75

1 Answers1

5

To make things work properly we need to forget about NSOperation and use this "trick"

dispatch_queue_t main_queue = dispatch_get_main_queue();
dispatch_async(main_queue, ^{

    [self createCustomViews];

    dispatch_async(main_queue, ^{

        [self addAnotherCustomViewToView];

    });
});
Abramodj
  • 5,709
  • 9
  • 49
  • 75
  • Hi! Question for you: Why is the nested dispatch_async necessary? (I trust that you wrote it that way for a reason. I'm just not seeing it yet.) Thanks! – Joe D'Andrea Mar 19 '13 at 20:28
  • To be honest I found this code around, and it just works. I don't really know more than this :-) – Abramodj Mar 21 '13 at 09:45
  • OK then! (Now I'm on a mission - hehe.) Thank you for posting it. :) – Joe D'Andrea Mar 21 '13 at 16:43
  • Nested dispatch_async for the main queue just doesn't make sense. You should/can create the views in the background thread, you add them on the main thread. Correct version can be found here: https://stackoverflow.com/a/15049772/4457396 – oyalhi Sep 24 '17 at 15:45