Ulaşım
- Adres:Batıkent Mh. 8910 Sk. 6. Etap 1H No: 18 Yeni Toki Eyyübiye / Şanlıurfa (Yeni Alım Satım Karşısı)
- Telefon:0 (545) 528 88 93
- eMail: info@alestaweb.com
Swift 6 ile gelen katı concurrency kuralları sizi bunalttı mı? "@MainActor şu hatası, data race uyarıları..." derken kod yazmak zorlaştı mı? Alesta Web olarak müjdemiz var: Swift 6.2 "Approachable Concurrency" ile bu sorunlar büyük ölçüde çözüldü! Bu kapsamlı rehberde (comprehensive Swift 6.2 concurrency guide) tüm yenilikleri ve migration stratejilerini anlatıyoruz.
Swift 6, memory safety'yi concurrency'ye de genişletti - bu harika bir özellik! Ancak pratikte birçok geliştirici aşırı compiler uyarıları ve hatalarıyla boğuştu.
Alesta Web olarak bu sorunları yaşayan geliştiricilere Swift 6.2'yi şiddetle öneriyoruz. Apple, bu geri bildirimleri dikkate aldı.
// Swift 6'da bu kod HATA verir:
class ViewModel {
var data: [String] = []
func loadData() async {
let result = await fetchFromNetwork()
data = result // ❌ Main actor-isolated property 'data'
// cannot be mutated from nonisolated context
}
}
// Çözüm için her yere @MainActor eklemek gerekiyordu:
@MainActor
class ViewModel {
var data: [String] = []
func loadData() async {
let result = await fetchFromNetwork()
data = result // ✅ Artık OK
}
}
Swift 6.2, Haziran 2025'te yayınlandı ve concurrency'yi çok daha "approachable" (yaklaşılabilir) hale getirdi. Alesta Web olarak en önemli değişiklikleri sizin için derledik:
| Özellik / Feature | Swift 6.0 | Swift 6.2 |
|---|---|---|
| Varsayılan isolation | nonisolated | @MainActor (opsiyonel) |
| Async function execution | Global executor'a atlar | Caller context'te kalır |
| Paralel kod işaretleme | Karmaşık | @concurrent ile kolay |
| Compiler hata sayısı | Çok fazla | Azaltıldı |
Approachable Concurrency, Swift 6.2'nin ana teması. Temel fikir şu: "Concurrency istisna olmalı, kural değil."
Yeni @MainActor by default seçeneği ile tüm kodunuz varsayılan olarak main thread'de çalışır. Paralel çalışması gereken kodları siz açıkça işaretlersiniz.
// Package.swift veya Build Settings'te
// Swift Package Manager
.executableTarget(
name: "MyApp",
swiftSettings: [
.enableUpcomingFeature("MainActorIsolationByDefault")
]
)
// Xcode Build Settings
SWIFT_UPCOMING_FEATURE_MAIN_ACTOR_ISOLATION_BY_DEFAULT = YES
Bu özellik özellikle şunlar için ideal (ideal for):
Eskiden nonisolated async fonksiyonlar her zaman global executor'a atlıyordu. Bu, birçok data-race hatası kaynağıydı.
// Swift 6.0 - Eski davranış
@MainActor
class ViewModel {
func updateUI() async {
// Burada main actor'da
await someAsyncWork()
// ❌ Artık global executor'da! Main actor'dan çıktık!
updateLabel() // HATA: Main actor'da değiliz
}
}
// Swift 6.2 - Yeni davranış (upcoming feature ile)
@MainActor
class ViewModel {
func updateUI() async {
// Burada main actor'da
await someAsyncWork()
// ✅ Hala main actor'da! Caller context korunuyor
updateLabel() // OK
}
}
Approachable Concurrency özelliğini etkinleştirdiğinizde compiler çok daha az hata ve uyarı üretecek (compiler will generate significantly fewer errors and warnings). Gerçek sorunlara odaklanabilirsiniz!
Swift 6.2'nin en önemli yeniliklerinden biri: @concurrent attribute. Bu, kodun paralel çalışmasını istediğinizi açıkça belirtmenizi sağlar.
// Paralel çalışması gereken fonksiyon
@concurrent
func processImage(_ image: UIImage) async -> UIImage {
// Bu fonksiyon background thread'de çalışabilir
// Main actor'dan bağımsız
let processed = await heavyImageProcessing(image)
return processed
}
// Kullanım
@MainActor
class ImageViewController: UIViewController {
func loadImage() async {
let originalImage = UIImage(named: "photo")!
// processImage paralel çalışır, sonuç gelince main'e döner
let processed = await processImage(originalImage)
// Hala main actor'dayız
imageView.image = processed
}
}
// nonisolated - sadece actor'dan bağımsız demek
// Async çağrılarda executor'a bağlı davranış değişebilir
nonisolated func compute() async -> Int {
// Davranış karmaşık olabilir
}
// @concurrent - açıkça "paralel çalışabilir" demek
// Semantik olarak daha net
@concurrent
func compute() async -> Int {
// Bu fonksiyon paralel çalışacak şekilde tasarlandı
}
@concurrent, kodunuzun niyetini daha net ifade eder. "Bu fonksiyon paralel çalışmalı" diyorsunuz. nonisolated ise sadece "actor'dan bağımsız" demek (just means independent from actor).
Alesta Web olarak Swift 6.0'dan 6.2'ye geçiş için önerilerimiz:
// Package.swift
let package = Package(
name: "MyApp",
platforms: [.iOS(.v17), .macOS(.v14)],
targets: [
.executableTarget(
name: "MyApp",
swiftSettings: [
// Approachable Concurrency özellikleri
.enableUpcomingFeature("InferSendableFromCaptures"),
.enableUpcomingFeature("GlobalActorIsolatedTypesUsability"),
// Main actor by default (UI uygulamaları için)
.enableUpcomingFeature("MainActorIsolationByDefault"),
// Async function isolation
.enableUpcomingFeature("AsyncCallerIsolationInheritance")
]
)
]
)
// ESKİ - GCD kullanımı
class DataManager {
private let queue = DispatchQueue(label: "com.app.data")
private var cache: [String: Data] = [:]
func getData(for key: String, completion: @escaping (Data?) -> Void) {
queue.async {
completion(self.cache[key])
}
}
}
// YENİ - Actor kullanımı
actor DataManager {
private var cache: [String: Data] = [:]
func getData(for key: String) -> Data? {
return cache[key] // Thread-safe, compiler garantili
}
func setData(_ data: Data, for key: String) {
cache[key] = data
}
}
// Kullanım
let manager = DataManager()
let data = await manager.getData(for: "key")
// Immutable struct zaten Sendable
struct UserConfig: Sendable {
let userId: String
let preferences: [String: String]
}
// Class için explicit conformance gerekli
final class NetworkConfig: Sendable {
let baseURL: URL
let timeout: TimeInterval
init(baseURL: URL, timeout: TimeInterval) {
self.baseURL = baseURL
self.timeout = timeout
}
}
// @unchecked Sendable - dikkatli kullanın!
class LegacyCache: @unchecked Sendable {
// Kendi thread-safety'nizi sağlamalısınız
private let lock = NSLock()
private var data: [String: Any] = [:]
}
// Swift 6 concurrency'ye uyumlu olmayan library'ler için
@preconcurrency import OldLibrary
// Bu, library'nin Sendable olmayan tiplerini
// geçici olarak tolere eder
// Library güncellenene kadar kullanın
Swift 6.x concurrency'de en sık karşılaşılan hatalar:
// HATA
class ViewController: UIViewController {
func loadData() {
Task {
await fetchData() // ❌ Capture of 'self' with non-sendable type
}
}
}
// ÇÖZÜM 1: @MainActor ekle
@MainActor
class ViewController: UIViewController {
func loadData() {
Task {
await fetchData() // ✅ OK
}
}
}
// ÇÖZÜM 2: Task.detached ile explicit capture
class ViewController: UIViewController {
func loadData() {
Task.detached { [weak self] in
guard let self else { return }
await self.fetchData()
}
}
}
// HATA
class DataProcessor {
func process() async {
async let result = heavyComputation() // ❌ Non-sendable
}
}
// ÇÖZÜM: Struct kullan veya actor yap
struct DataProcessor { // Struct otomatik Sendable
func process() async {
async let result = heavyComputation() // ✅ OK
}
}
// VEYA
actor DataProcessor { // Actor da OK
func process() async {
async let result = heavyComputation() // ✅ OK
}
}
// HATA
@MainActor
class ViewModel {
var items: [String] = []
nonisolated func updateFromBackground() async {
items = ["new"] // ❌ Cannot mutate main actor property
}
}
// ÇÖZÜM: MainActor.run kullan
@MainActor
class ViewModel {
var items: [String] = []
nonisolated func updateFromBackground() async {
let newItems = await processInBackground()
await MainActor.run {
items = newItems // ✅ OK
}
}
}
Bu makalede kullanılan bilgiler aşağıdaki güvenilir kaynaklardan derlenmiştir:
Alesta Web olarak tüm bilgileri doğruladık (we verified all information).
Swift 6.2'nin Approachable Concurrency özellikleri ile artık concurrency kabus olmaktan çıkıyor. Alesta Web olarak iOS/macOS geliştiricilerine Swift 6.2'ye geçmeyi şiddetle öneriyoruz. Compiler hataları azalacak, kod yazmak kolaylaşacak!
Hızlı Özet / Quick Summary:
Faydalı Linkler / Useful Links:
© 2026 AlestaWeb - Tüm hakları saklıdır. | alestaweb.com