ios - 为什么在init中使用DispatchQueue时报错 '' self'used before self.init call'?

标签 ios iphone swift swift3

我在下面的代码中遇到了这些错误(Xcode 9):

convenience init(dictionary: [String: AnyObject], context: NSManagedObjectContext) {
    guard let entity = NSEntityDescription.entity(forEntityName: "Photo", in: context) else {
        fatalError("No Entity name Found")
    }

    DispatchQueue.main.async {
        self.init(entity: entity, insertInto: context)
        self.title = dictionary[FlickrClient.JSONResponseKeys.title] as? String
        self.path = dictionary[FlickrClient.JSONResponseKeys.mediumURL] as? String
    }
}

它在没有 DispatchQueue.main.async 的情况下工作正常,但我需要实现它,因为应用程序不是线程安全的。提前致谢!

最佳答案

问题是您在传递给 DispatchQueue.main.async 的闭包中使用了 self。当您在闭包内使用 self 时,它会被闭包捕获,这算作将 self 传递给某物。在完成初始化 self 之前,您不能这样做。

另外,想一想。如果允许这样做,初始化程序将在初始化实际完成之前完成,因为主线程仍然有工作要做,并且初始化程序在进行切换后几乎已经完成。

如果您需要异步初始化某些东西,请改用工厂模式:

static func make(foo: Foo, bar: Bar, baz: Whatever, handler: (Widget) -> ()) {
    DispatchQueue.main.async {
        guard let thingy = Thingy(xyzzy: plugh) else { fatalError("I DON'T LIKE SPAM") }

        handler(Widget(thingy: thingy))
    }
}

关于ios - 为什么在init中使用DispatchQueue时报错 '' self'used before self.init call'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48046552/

相关文章:

swift - 无法将类型 'nsindexpath?' 的值转换为预期的参数类型 '[nsindexpath]'

ios - 如何设置本地通知在首次设置通知后每秒触发一次?

ios - "[[FBSDKAccessToken currentAccessToken] hasGranted:@"publish_actions "]"始终返回 false

ios - 使用地址簿作为数据源

iOS:以编程方式创建的 UINavigationController 的导航栏未扩展到安全区域

ios - 如何自动从 viewcontroller 重新加载数据?

ios - 当他们已经是联系人时,使用 CallKit 识别来电者

ios - UITableView 重新排列单元格

c++ - 当与服务器的连接未保留时使用 SSL

iPhone应用程序: Can I open an app from a link in a website?