Xcode [UIView initWithFrame:]只能在主线程中使用

时间:2022-10-30 08:46:52

I'm trying to render some views in a separate thread to not affect the main thread. That was never a problem before Xcode 9. Now my unit tests crash here.

我试图在一个单独的线程中呈现一些视图,以不影响主线程。这在Xcode 9之前从来都不是问题。现在我的单元测试崩溃了。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImage *snapShot = [self generateShadowImage];
    dispatch_async(dispatch_get_main_queue(), ^{
        imageView.image = snapShot;
    });
});

...

- (UIImage *)generateShadowImage {

    // It crashes here:
    UIView *shadowView = [[UIView alloc] initWithFrame:CGRectZero];
    ...
}

Why should i not be able to render UI elements for later use in a thread other than the main thread?

为什么我不能呈现UI元素供以后在主线程以外的线程中使用?

2 个解决方案

#1


18  

XCode 9 has a new runtime Main Thread Checker that detects call to UIKit from a background thread and generate warnings.

XCode 9有一个新的运行时主线程检查器,用于检测从后台线程调用UIKit并生成警告。

I know its meant to generate warnings and not crash the app, but you can try disabling Main Thread Checker for your test target.

我知道这意味着生成警告,而不是崩溃的应用程序,但您可以尝试禁用主线程检查器为您的测试目标。

Xcode [UIView initWithFrame:]只能在主线程中使用

I tried this code in a sample project, the debugger paused at the issue (as it is supposed to), but the app didn't crash.

我在一个示例项目中尝试了这段代码,调试器在这个问题上暂停(正如它应该的那样),但应用程序没有崩溃。

override func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.global().async {
        let v = UIView(frame: .zero)
    }
}

#2


5  

You can use this function

你可以用这个函数

func downloadImage(urlstr: String, imageView: UIImageView) {
    let url = URL(string: urlstr)!
    let task = URLSession.shared.dataTask(with: url) { data, _, _ in
        guard let data = data else { return }
        DispatchQueue.main.async { // Make sure you're on the main thread here
            imageview.image = UIImage(data: data)
        }
    }
    task.resume()
}

How to use this function?

如何使用这个函数?

downloadImage(urlstr: "imageUrl", imageView: self.myImageView)

#1


18  

XCode 9 has a new runtime Main Thread Checker that detects call to UIKit from a background thread and generate warnings.

XCode 9有一个新的运行时主线程检查器,用于检测从后台线程调用UIKit并生成警告。

I know its meant to generate warnings and not crash the app, but you can try disabling Main Thread Checker for your test target.

我知道这意味着生成警告,而不是崩溃的应用程序,但您可以尝试禁用主线程检查器为您的测试目标。

Xcode [UIView initWithFrame:]只能在主线程中使用

I tried this code in a sample project, the debugger paused at the issue (as it is supposed to), but the app didn't crash.

我在一个示例项目中尝试了这段代码,调试器在这个问题上暂停(正如它应该的那样),但应用程序没有崩溃。

override func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.global().async {
        let v = UIView(frame: .zero)
    }
}

#2


5  

You can use this function

你可以用这个函数

func downloadImage(urlstr: String, imageView: UIImageView) {
    let url = URL(string: urlstr)!
    let task = URLSession.shared.dataTask(with: url) { data, _, _ in
        guard let data = data else { return }
        DispatchQueue.main.async { // Make sure you're on the main thread here
            imageview.image = UIImage(data: data)
        }
    }
    task.resume()
}

How to use this function?

如何使用这个函数?

downloadImage(urlstr: "imageUrl", imageView: self.myImageView)