When using implicitly unwrapped optionals, the priority of protocol extensions seems to be wrong. Consider this example:
import SwiftUI
protocol SpecializedView: View {}
struct MyView: SpecializedView {
var body: some View {
EmptyView()
}
}
extension View {
var isSpecialized: Bool {
false
}
}
extension SpecializedView {
var isSpecialized: Bool {
true
}
}
I've only been able to reproduce the issue with SwiftUI Views. This is a minimally working example that exhibits the behavior:
@main
struct ProtocolExtensions: App {
var body: some Scene {
WindowGroup {
Button("Test") {
let view1: MyView = MyView()
let view2: MyView? = MyView()
let view3: MyView! = MyView()
print(view1.isSpecialized) // true
print(view2.isSpecialized) // false -> Why does this compile?
print(view2!.isSpecialized) // true
print(view3.isSpecialized) // false
print(view3!.isSpecialized) // true
}
}
}
}
Is this a bug? I'm using Xcode 13.2.1
Lantua
2
It's not written in the conformance list, but X? where X is a View is also a View. So you're using MyView? implementation of isSpecialized, which is the default implementation, i.e., false.
2 Likes
Hm, does that mean there is something like this in the SwiftUI framework?
extension Optional: View where Wrapped: View {
var body: some View {
Group {
if let view = self {
view
} else {
EmptyView()
}
}
}
}
1 Like
Lantua
4
Probably, it's kinda tricky to jump to conformance definition. So yea, that's essentially what happened, and that's why you see an alternating true/false.
2 Likes
ole
(Ole Begemann)
5
Almost. The documentation tells us that Optional.Body == Never:
extension Optional: View where Wrapped: View {
typealias Body = Never
var body: some View { fatalError() }
}
So Optional is one of the built-in views whose body property can never produce a value. SwiftUI knows how to render these views "natively".
1 Like