【问题标题】:NSOperation: addsubview in the main thread and slownessNSOperation:在主线程中添加子视图和缓慢
【发布时间】:2012-05-07 19:21:56
【问题描述】:

我已经实现了以下 NSOperation,来绘制 N 自定义视图

- (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");
}

在customView的drawRect方法中我有

- (void)drawRect {

    <<Drawing code>>

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

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

因此,当所有视图都绘制完毕时,委托会收到通知。

问题是在“操作完成”日志之后,我需要大约 5 秒才能看到第一个“已绘制”日志。

为什么会这样?一般来说,我应该如何表现才能找出哪一行代码执行了这么多时间?

----- 编辑 ------

有时(例如 10 次中的 1 次)这样做会导致崩溃,因为我不应该从 NSOperation 调用 addsubview,因为它不是线程安全的。所以我把它改成:

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

现在我没有崩溃了,但是这个过程需要很长时间才能执行!比以前多了 5 倍。

为什么这么慢?

【问题讨论】:

    标签: nsoperation drawrect nsoperationqueue


    【解决方案1】:

    为了让事情正常运行,我们需要忘记 NSOperation 并使用这个“技巧”

    dispatch_queue_t main_queue = dispatch_get_main_queue();
    dispatch_async(main_queue, ^{
    
        [self createCustomViews];
    
        dispatch_async(main_queue, ^{
    
            [self addAnotherCustomViewToView];
    
        });
    });
    

    【讨论】:

    • 嗨!给你的问题:为什么嵌套的 dispatch_async 是必要的? (我相信你这样写是有原因的。我只是还没有看到它。)谢谢!
    • 老实说,我在周围找到了这段代码,它确实有效。我真的不知道比这更多:-)
    • 好吧! (现在我正在执行一项任务 - 呵呵。)感谢您发布它。 :)
    • 主队列的嵌套 dispatch_async 没有意义。您应该/可以在后台线程中创建视图,然后将它们添加到主线程中。正确的版本可以在这里找到:stackoverflow.com/a/15049772/4457396
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多