Назад към всички

Swift

// Write safe Swift code avoiding memory leaks, optional traps, and concurrency bugs.

$ git log --oneline --stat
stars:1,933
forks:367
updated:March 4, 2026
SKILL.mdreadonly
SKILL.md Frontmatter
nameSwift
slugswift
version1.0.1
descriptionWrite safe Swift code avoiding memory leaks, optional traps, and concurrency bugs.
metadata[object Object]

Quick Reference

TopicFile
Optionals, nil safety, force unwrapoptionals.md
Retain cycles, weak refs, closuresmemory.md
async/await, actors, Sendable, value typesconcurrency.md
JSON encoding/decoding trapscodable.md
Protocols, collections, strings, errors, buildtypes.md
SwiftUI state (@State, @Binding, Combine)swiftui.md
Property wrappers, actors, result builders, macrosadvanced.md
XCTest pitfalls, SPM gotchastesting.md

Critical Rules

Memory & Safety

  • Force unwrap ! crashes on nil — use guard let or if let instead
  • Closures capturing self strongly create retain cycles — use [weak self] in escaping closures
  • Delegates must be weak — strong delegate = object never deallocates
  • try! crashes on any error — never use in production paths
  • removeFirst() crashes on empty — use popFirst() for safety

Concurrency

  • async let starts immediately — not when you await
  • Actor reentrancy at every await — state may change between suspension points
  • @MainActor doesn't guarantee immediate main thread — it's queued
  • Sendable conformance violations crash at runtime — compiler warnings are errors

Types & Collections

  • Protocol extensions don't override — static dispatch ignores subclass implementation
  • Mutating struct in collection requires reassignment — array[0].mutate() doesn't work
  • String.Index from one string invalid on another — even if contents match

SwiftUI

  • @StateObject owns, @ObservedObject borrows — recreating view loses ObservedObject state
  • @EnvironmentObject crashes if not injected — no compile-time check
  • View identity change resets all @State — changing ID loses state

Build

  • print() builds strings even in release — remove or use os_log
  • Generic code bloat — specialized for each type, increases binary size