当我用@MainAct或标记一个带有异步函数的协议时,它的一致性没有指定它的函数是异步的,它不在主线程上执行.我不知道这是不是一个窃听器.

例如,给定以下协议和实施:

@MainAct或
protocol MyMainAct或Protocol {
    func doStuff() async
}

struct MyMainAct或Struct: MyMainAct或Protocol {
    nonisolated init() {}
    func doStuff()  {
        print(">>> \(Thread.isMainThread)")
    }
}

当我执行此代码时:

Task {
    let dependency: MyMainAct或Protocol = MyMainAct或Struct()
    print(">>> \(Thread.isMainThread)")
    await dependency.doStuff()
}

这两个打印语句都在后台线程中运行.

但通过以下两种方式的调整

@MainAct或
protocol MyMainAct或Protocol {
    func doStuff()
}

struct MyMainAct或Struct: MyMainAct或Protocol {
    nonisolated init() {}
    func doStuff()  {
        print(">>> \(Thread.isMainThread)")
    }
}

@MainAct或
protocol MyMainAct或Protocol {
    func doStuff() async
}

struct MyMainAct或Struct: MyMainAct或Protocol {
    nonisolated init() {}
    func doStuff() async  {
        print(">>> \(Thread.isMainThread)")
    }
}

I get the c或rect result, where the body of the function inside the struct runs in the main thread.

Is this expected behavi或? What is the explanation behind it.

推荐答案

根据前global actor inference rules名,

在与其主要定义相同的源文件中,符合全局执行元限定协议的非执行元类型推断执行元与该协议隔离

因此,如果您将它们放在同一个源文件中,MyMainActorStruct应该也是MainActor隔离的,doStuff也是如此.

因此,当您try 在doStuff中将UIView初始化时,您不会收到错误.然而,当您dotry 在运行时执行此操作时,您会在控制台中看到这样的日志(log):"在后台线程上调用了UIAPI".这不应该发生.这种行为显然是一个漏洞.

请注意,即使您将@MainActorMyMainActorStruct相加,甚至将doStuffdoStuff相加,此行为仍将保持不变.

为了找出这是如何发生的,我比较了以下代码(See the full SIL on godbolt.org)生成的sIL:

@MainActor
protocol MyMainActorProtocol {
    func doStuff() async
}

@MainActor
struct MyMainActorStruct: MyMainActorProtocol {
    nonisolated init() {}
    func doStuff() async { }
}
@MainActor
protocol MyMainActorProtocol {
    func doStuff() async
}

@MainActor
struct MyMainActorStruct: MyMainActorProtocol {
    nonisolated init() {}
    func doStuff() { }
}

前者在doStuff有一条hop_to_executor %4 : $MainActor线,而后者没有.

这与之前在非常类似的情况下发生的(固定的)bug非常相似.该错误大约是actor用非async代码实现async协议要求,例如

protocol Foo {
    func foo() async
}

actor FooActor : Foo {
    func foo() { }
}

同样的演员-HOP也不见了.尽管这个错误已经修复,但很可能是因为它们也忘记了在全局参与者的情况下发出一个参与者跳.

Ios相关问答推荐

创建带有Flutter 翼的会所头像

使用AVCaptureEventInteraction捕获音量按键快门

AVFoundation Camera推出变焦SWIFT

OBJC @selector 在另一个实现中不起作用

封装 Swift 导入

如何在Combine发布者之间强制执行最小延迟

ITMS-90432:将应用上传到应用store 时出现问题

iOS 16.4 更新后 Xcode 14.3 构建错误:找不到 libarclite_iphoneos.a,链接器命令失败

DllImport with .a file for iOS in MAUI

SwiftUI - 如何从主题感知命名 colored颜色 中获取正确的 RGB 值?

为 ColorPicker 创建一个名为 Color 的计算变量的绑定

`Task` 在内部调用异步函数时阻塞主线程

Flutter 错误:CocoaPods not installed or not in valid state.

以编程方式获取故事板 ID?

标题为 UIImage 的导航栏

从 NSUserDefaults 字典 iOS 中删除所有键

如何以编程方式切换 UISegmentedControl?

以编程方式 Select UITextField 中的所有文本

有什么方法可以加粗 NSString 的一部分?

UITextView 内容插图