> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/ios/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/ios/swift/concurrency/sendable/has-non-sendable-type.md).

# has non-Sendable type

⟩

[Swift](/ios/swift.md) ⟩ [Concurrency](/ios/swift/concurrency.md) ⟩ [Sendable](/ios/swift/concurrency/sendable.md) ⟩ :lady\_beetle: <mark style="color:red;">has non-Sendable type</mark>

{% hint style="danger" %}
Stored property '`shape`' of '[Sendable](/ios/swift/concurrency/sendable.md)'-conforming struct '`MyAnyShape`' <mark style="color:red;">has non-sendable type</mark> '`(CGRect)->Path`'
{% endhint %}

:point\_right: [ChatGPT conversation](https://chatgpt.com/share/67528aa6-d8b8-800e-b03e-5bd2aeae2561)

```swift
import SwiftUI

// ⭐️ Shape is Sendable
struct MyAnyShape: Shape {
    
    // ⭐️ properties must be Sendable too.
    private let shape: (CGRect) -> Path   // 🐞 error
    
    init<S: Shape>(_ wrapped: S) {
        self.shape = { rect in
            wrapped.path(in: rect)
        }
    }
    
    func path(in rect: CGRect) -> Path {
        shape(rect)
    }
}
```

## 錯誤原因

1. &#x20;`MyAnyShape` 遵循 [Shape](/ios/swiftui/shapes/shape.md)，但 Shape 隱含遵循 [Sendable](/ios/swift/concurrency/sendable.md) 的規定(用於 [Concurrency](/ios/swift/concurrency.md) 的安全保障）。
   * `Sendable` 要求 `struct` 中所有屬性也必須是 `Sendable`。
   * 但 `shape` 屬性是閉包([closure](/ios/swift/type/category/basic/closure.md))，並不自動符合 Sendable，因為它可能捕獲非 Sendable 的值。
2. &#x20;Swift Concurrency 的影響
   * 在 Swift 5.5 或更高版本中，並行程式設計([Concurrency](/ios/swift/concurrency.md))會對某些類型進行更嚴格的型別檢查，特別是用於 @Sendable 閉包的情況。

## 解決方案 <a href="#solutions" id="solutions"></a>

{% tabs %}
{% tab title="1" %}
方案一：<mark style="color:yellow;">直接儲存</mark> [Shape](/ios/swiftui/shapes/shape.md) <mark style="color:yellow;">實例</mark>(`wrappedShape`)，而不是閉包(closure)，完全避開 [Sendable](/ios/swift/concurrency/sendable.md) 的問題。這樣的寫法具有<mark style="color:yellow;">較大的靈活性</mark>，如果你有很多種類的 [Shape](/ios/swiftui/shapes/shape.md)，建議用此寫法。

```swift
import SwiftUI

struct MyAnyShape: Shape {

    // ⭐️ 直接儲存 Shape 實例
    private var wrappedShape: any Shape

    init<S: Shape>(_ wrapped: S) {
        self.wrappedShape = wrapped
    }

    func path(in rect: CGRect) -> Path {
        wrappedShape.path(in: rect)
    }
}
```

{% endtab %}

{% tab title="2" %}
方案二：如果 [Shape](/ios/swiftui/shapes/shape.md) <mark style="color:yellow;">類型有限</mark>，<mark style="color:yellow;">可用</mark> [enum](/ios/swift/type/category/basic/enum.md) <mark style="color:yellow;">來區分</mark>不同的形狀：

```swift
import SwiftUI

// ⭐️ 直接用 enum 管理形狀，不需用泛型或閉包
enum MyShape: Shape {

    case circle
    case roundedRectangle(cornerSize: CGSize)

    // ⭐️ Shape requirement
    func path(in rect: CGRect) -> Path {
        switch self {
            case .circle:
                return Circle().path(in: rect)
            case .roundedRectangle(let cornerSize):
                return RoundedRectangle(cornerSize: cornerSize).path(in: rect)
        }
    }
}
```

:point\_right: 應用： [view.clipShape()](/ios/swiftui/view/drawing/view.clipshape.md)
{% endtab %}

{% tab title="3" %}
方案三：將 `MyAnyShape` 明確標記為不需符合 `Sendable`。適合熟悉 Swift Concurrency，且確認程式邏輯是 thread-safe 時使用。

```swift
import SwiftUI

struct MyAnyShape: Shape {
    
    // ⭐️ 不符合 Sendable 的屬性
    private let shape: (CGRect) -> Path

    init<S: Shape>(_ wrapped: S) {
        self.shape = { rect in
            wrapped.path(in: rect)
        }
    }

    func path(in rect: CGRect) -> Path {
        shape(rect)
    }
}

// ⭐️ 添加 @unchecked Sendable 以避免 Sendable 錯誤
extension MyAnyShape: @unchecked Sendable {}
```

{% endtab %}

{% tab title="📘 手冊" %}

* [Swift](https://developer.apple.com/documentation/swift) ⟩ [Standard Library](https://developer.apple.com/documentation/swift/swift-standard-library) ⟩ [Concurrency](https://developer.apple.com/documentation/swift/concurrency) ⟩ [Sendable](https://developer.apple.com/documentation/Swift/Sendable)
  {% endtab %}

{% tab title="👥 相關" %}

* :parking: [Shape](/ios/swiftui/shapes/shape.md)： must be <mark style="color:purple;">Sendable</mark>.
* :package: [AnyShape](/ios/swiftui/shapes/shape/anyshape.md)：[type-erased](/ios/swift/type/erasure.md) shape value.
* :bulb: [用 enum 封裝不同型別](/ios/swift/type/category/basic/enum/wrap-types.md)
  {% endtab %}
  {% endtabs %}
