Mobil geliştirmede Swift'e özgü özellikler: nedir, temel özellikler ve nasıl çalışır

Yazar: IT Sectr Yayınlanma: 2026-06-25 Okuma süresi: 17 dk

Swift, Objective-C'nin gücünü modern dillerin güvenliğiyle birleştiren Apple'ın programlama dilidir. Diğer birçok dilden farklı olarak Swift, benzersiz yapılar sunar: otomatik kopyalama ile değer türleri, derleyici düzeyinde izolasyon ile Actors, özellik mantığını yeniden kullanmak için Property Wrappers ve klasik kalıtıma alternatif olarak Protokol Odaklı Programlama.Apple Swift Dokümantasyonu'na göre, bu özellikler kodu daha güvenli ve verimli hale getirir.

Önemli Noktalar

  • Struct — değer türü, atamada kopyalanır, kalıtımı desteklemez. Class — referans türü, referansla iletilir, kalıtım ve deinit'i destekler.
  • Actor — derleyici düzeyinde izolasyon ile thread güvenli referans türü. Derleyici, farklı görevlerden değiştirilebilir duruma eşzamanlı erişimi engeller.
  • Property Wrappers — @Published, @State, @Binding, SwiftUI ve Combine'da özellik mantığını kapsülleyerek tekrar eden kodu ortadan kaldırır.
  • Generics belirli bir türe bağlanmadan tür güvenli fonksiyonlar ve yapılar yazmayı sağlar. Protokol Odaklı Programlama, sınıf hiyerarşisi yerine extension + protocol kullanır.
  • Enum ilişkili değerlerle — durumları modellemek için güçlü bir araç. Her durum, farklı türlerde rastgele veri kümesi depolayabilir.

Swift'te Struct vs Class: değer türleri ve referans türleri

Swift'te struct bir değer türüdür, class ise bir referans türüdür. Bu temel fark, atama, fonksiyonlara geçirme ve bellek yönetimi sırasındaki davranışı belirler. Struct her atamada tamamen kopyalanır, class referansla iletilir — yalnızca heap'teki nesneye işaretçi kopyalanır.

Struct'ın Değer Semantiği

Struct otomatik olarak değer semantiğini uygular — her örnek bağımsızdır. Bir struct özelliğinin değiştirilmesi yalnızca var ile mümkündür ve özellikleri değiştiren metotlar mutating olarak işaretlenmelidir. Struct kalıtımı desteklemez ancak protokollere uyum sağlayabilir. Swift'in standart kütüphanesi String, Array, Dictionary, Int, Bool için struct kullanır — tüm temel türler değer türleridir.

swift
struct User {
    let id: Int
    var name: String

    mutating func updateName(_ newName: String) {
        name = newName
    }
}

var user1 = User(id: 1, name: "Alice")
var user2 = user1
user2.updateName("Bob")
// user1.name === "Alice", user2.name === "Bob"
// Tam kopya — bağımsız örnekler

Class'ın Referans Semantiği

Class heap'te depolanır ve referans eşitliğini destekler. Birden çok değişken aynı nesneye referans verebilir, bir referans üzerinden yapılan değişiklikler diğer tüm referanslardan görülebilir. Class kalıtımı destekler, metot geçersiz kılmaya (override) izin verir, kaynak temizliği için deinit'e sahiptir. Swift'te struct'tan daha az kullanılır — Apple, struct ile başlamayı ve yalnızca kalıtım veya referans semantiği gerektiğinde class'a geçmeyi önerir.

swift
class Car {
    let model: String
    var speed: Int

    init(model: String, speed: Int) {
        self.model = model
        self.speed = speed
    }

    func accelerate(_ amount: Int) {
        speed += amount
    }
}

let car1 = Car(model: "Tesla", speed: 0)
let car2 = car1
car2.accelerate(50)
// car1.speed === 50, car2.speed === 50
// Aynı referans — değişiklikler her yerde görünür

struct ve class arasındaki seçim veri semantiğine bağlıdır. Yapılandırmalar, veri modelleri ve durumlar için struct kullanın — kopyalama daha güvenli ve öngörülebilirdir. Kimliği olan nesneler (kullanıcı oturumu, veritabanı bağlantısı) ve kalıtım gerektiğinde class kullanın.

Actor — Swift'te thread güvenliği

Actor, değiştirilebilir durumunu eşzamanlı erişime karşı koruyan bir referans türüdür. Swift derleyicisi, actor değişkenlerine yalnızca aynı actor bağlamından erişilebileceğini garanti eder — herhangi bir dış erişim derleme hatasına neden olur. Bu, manuel kilitler olmadan dil düzeyinde veri yarışlarını önler.

Actor İzolasyonu

Tüm actor özellikleri ve metotları varsayılan olarak izole edilmiştir. Dışarıdan bir actor metodunu çağırmak await gerektirir — Swift yürütmeyi actor'e geçirir ve geri döndürür. Actor erişimi sıralı olarak senkronize eder: farklı görevlerden gelen istekler sıraya alınır. Bu, actor içinde tutarlı durum sağlar. İzole olmayan metotlar (nonisolated) await olmadan çağrılabilir ancak değiştirilebilir özelliklere erişemez.

swift
actor BankAccount {
    private var balance: Double

    init(initialBalance: Double) {
        balance = initialBalance
    }

    func deposit(amount: Double) {
        balance += amount
    }

    func withdraw(amount: Double) throws {
        guard balance >= amount else {
            throw BankError.insufficientFunds
        }
        balance -= amount
    }

    nonisolated func accountInfo() -> String {
        return "Banka Hesabı"
    }
}

let account = BankAccount(initialBalance: 1000)
await account.deposit(amount: 500)
// balance = 1500 — atomik, yarış durumu yok

Actor, birden çok görevin eşzamanlı olarak veri okuyup yazdığı durum yöneticileri, önbellekler ve ağ hizmetleri için kullanışlıdır. NSLock veya DispatchQueue ile manuel senkronizasyonun aksine, actor derleme zamanında kontrol edilir — hata yapmak imkansızdır. İzolasyon hataları çalışma zamanında değil, derleme zamanında ortaya çıkar.

Property Wrappers: @Published, @State, @Binding

Property Wrapper, bir özelliğin bildirimini değiştirmeden ona davranış ekleyen bir ek açıklamadır. SwiftUI ve Combine, görünüm durumunu yönetmek için yerleşik sarmalayıcılar sağlar. Derleyici, özellik erişimini sarmalayan, gözlem, senkronizasyon veya dönüştürme mantığı ekleyen kod üretir.

@Published ve @State

@Published, ObservableObject'e uyum sağlayan sınıflarda değişiklikleri otomatik olarak yayınlamak için kullanılır. Combine aboneleri her güncellemede bildirim alır. @State, SwiftUI görünümünün yerel durumudur. @State değiştiğinde SwiftUI görünümü otomatik olarak yeniden çizer. @Binding, verilere sahip olmadan üst ve alt görünüm arasında çift yönlü bağlantı oluşturur.

swift
import SwiftUI
import Combine

@main
struct CounterApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class CounterViewModel: ObservableObject {
    @Published var count: Int = 0

    func increment() {
        count += 1
    }
}

struct ContentView: View {
    @State private var greeting: String = "Merhaba"
    @StateObject private var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            CounterDisplay(count: $viewModel.count)
            Text(greeting)
            Button("Arttır", action: viewModel.increment)
        }
    }
}

struct CounterDisplay: View {
    @Binding var count: Int

    var body: some View {
        Text("Sayı: \(count)")
    }
}

Özel Property Wrapper'lar @propertyWrapper ve wrappedValue alanına sahip bir yapı kullanılarak oluşturulur. Bu, doğrulama, normalleştirme, UserDefaults depolama gibi mantığın yeniden kullanılmasını sağlar. Property Wrapper'lar tekrar eden kodu önemli ölçüde azaltır ve ek açıklama yoluyla geliştiricinin niyetini açık hale getirir.

swift
@propertyWrapper
struct Clamped<T: Comparable> {
    private var value: T
    let range: ClosedRange<T>

    init(wrappedValue: T, range: ClosedRange<T>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }

    var wrappedValue: T {
        get { value }
        set { value = min(max(newValue, range.lowerBound), range.upperBound) }
    }
}

struct Settings {
    @Clamped(range: 0...100) var volume: Int = 50
}

var s = Settings()
s.volume = 150
// s.volume === 100 — değer otomatik olarak sınırlandı

Generics ve Protokol Odaklı Programlama

Generics, tür güvenliğini kaybetmeden esnek kod yazmak için Swift'in güçlü bir mekanizmasıdır. Genel işlevler ve türler, kısıtlamaları karşılayan herhangi bir türle çalışır. Protokol Odaklı Programlama (POP), protocol + extension'ın klasik sınıf kalıtımının yerini aldığı ve davranış kompozisyonu sağlayan bir Swift paradigmasıdır.

Genel Kısıtlamalar ve İlişkili Türler

Swift, protokollerle (where cümleleri) genel parametreleri kısıtlamaya izin verir. İlişkili türe sahip protokol, protokoller için genel eşdeğerdir: somut tür, uyum anında belirlenir. Bu, tür güvenli koleksiyonlar ve algoritmaların temelidir. Swift'in standart kütüphanesi Generics'i aktif olarak kullanır: Array, Dictionary, Optional — hepsi genel türlerdir.

swift
protocol Cacheable {
    associatedtype Key: Hashable
    associatedtype Value

    func get(_ key: Key) -> Value?
    mutating func set(_ value: Value, for key: Key)
}

struct MemoryCache<K: Hashable, V>: Cacheable {
    private var storage: [K: V] = [:]

    typealias Key = K
    typealias Value = V

    func get(_ key: K) -> V? {
        return storage[key]
    }

    mutating func set(_ value: V, for key: K) {
        storage[key] = value
    }
}

func firstMatch<T: Equatable>(in array: [T], target: T) -> Int? {
    for (index, item) in array.enumerated() {
        if item == target {
            return index
        }
    }
    return nil
}

let numbers = [10, 20, 30, 40]
let index = firstMatch(in: numbers, target: 30)
// index === 2 — tüm Equatable türleri için tek bir genel metot

Protokol Extension'ı ve Varsayılan Uygulamalar

Protokol extension'ı POP'un ana mekanizmasıdır. Bir extension'da protokol metotlarının varsayılan uygulaması sağlanabilir. Protokole uyum sağlayan türler bu uygulamayı ücretsiz alır ve gerektiğinde geçersiz kılabilir. Bu, sınıf kalıtımı olmadan davranış hiyerarşileri oluşturmayı sağlar — Swift'te bulunmayan çoklu kalıtıma bir alternatif.

swift
protocol Drivable {
    var speed: Double { get set }
    func drive()
}

extension Drivable {
    func drive() {
        if speed > 0 {
            print("\(speed) km/s hızla sürüş")
        }
    }
}

struct Bicycle: Drivable {
    var speed: Double = 15
}

struct Plane: Drivable {
    var speed: Double = 900

    func drive() {
        print("\(speed) km/s hızla uçuş")
    }
}

let bike = Bicycle()
bike.drive() // "15.0 km/s hızla sürüş" — varsayılan

let plane = Plane()
plane.drive() // "900.0 km/s hızla uçuş" — geçersiz kılındı

Extension ile POP, birden çok protokol aracılığıyla kompozisyon sağlar — bir tür birden çok protokole uyum sağlayabilir ve uygulamalarını alabilir. Bu, tüm hiyerarşinin sabit olduğu tek sınıf kalıtımından daha esnektir. Swift'in standart kütüphanesi POP üzerine inşa edilmiştir: CustomStringConvertible, Equatable, Hashable, Codable — hepsi extension'a sahip protokollerdir.

İlişkili değerler ve Extension ile Enum

Enum Swift'te diğer dillere göre önemli ölçüde daha güçlü bir yapıdır. Her durum ilişkili değerlere sahip olabilir — herhangi bir türden rastgele veri kümesi. Extension ve pattern matching ile birleştiğinde enum, durumları, işlem sonuçlarını ve sonlu durum makinelerini modellemenin temeli haline gelir.

İlişkili Değerler ve Pattern Matching

İlişkili değerler, her durumun benzersiz veriler depolamasına izin verir. Örneğin, loading durumu veri içermez, success sonucu içerir, failure bir hata içerir. Switch ile pattern matching, ilişkili değerleri çıkarır ve her durumu işler. Derleyici kapsamlılığı kontrol eder (exhaustive switch) — bu unutulan durumları ortadan kaldırır.

swift
enum NetworkResult<T> {
    case loading
    case success(T)
    case failure(Error)
}

enum MediaFile {
    case image(url: URL, width: Int, height: Int)
    case video(url: URL, duration: Double)
    case audio(url: URL, bitrate: Int)
}

func handle(_ result: NetworkResult<String>) {
    switch result {
    case .loading:
        print("Yükleniyor...")
    case .success(let data):
        print("Alındı: \(data)")
    case .failure(let error):
        print("Hata: \(error.localizedDescription)")
    }
}

let file = MediaFile.video(url: URL(string: "https://example.com/video.mp4")!, duration: 120)

if case .video(let url, let duration) = file {
    print("Video \(url) süre \(duration)s")
}

Enum için Extension

Swift, enum için extension aracılığıyla metot, hesaplanmış özellik ve protokol uyumu eklemeye izin verir. Bu, orijinal bildirimi değiştirmeyi gerektirmez — kod temiz ve modüler kalır. Extension'daki metotlar ilişkili değerlerle çalışabilir, türetilmiş verileri hesaplayabilir ve iş mantığını uygulayabilir.

swift
extension MediaFile {
    var fileName: String {
        switch self {
        case .image(let url, _, _),
             .video(let url, _),
             .audio(let url, _):
            return url.lastPathComponent
        }
    }

    var description: String {
        switch self {
        case .image(_, let w, let h):
            return "Resim \(w)x\(h)"
        case .video(_, let d):
            return "Video \(d)s"
        case .audio(_, let b):
            return "Ses \(b) kbps"
        }
    }
}

extension MediaFile: Equatable {
    static func == (lhs: MediaFile, rhs: MediaFile) -> Bool {
        return lhs.fileName == rhs.fileName
    }
}

let files: [MediaFile] = [file]
files.forEach { print($0.description) }
// "Video 120.0s"

İlişkili değerler + Extension ile Enum, Kotlin'deki sealed sınıfların veya diğer dillerdeki ayrımcı birleşimlerin yerine geçer. Swift bu kombinasyonu Result (standart kütüphanede standart bir tür), Optional (Optional, .none ve .some ile bir enum'dur) ve SwiftUI'de durum yönetimi için kullanır. Pattern matching, tüm durumların işlenmesini garanti eder — çalışma zamanı hataları imkansızdır.

Sıkça Sorulan Sorular

Swift'te struct, class'tan nasıl farklıdır?

Struct — değer türü, atamada kopyalanır, kalıtımı desteklemez. Class — referans türü, referansla iletilir, kalıtım, deinit ve kimlik kontrolünü (===) destekler. Apple, struct ile başlamayı ve yalnızca referans semantiği gerektiğinde class'a geçmeyi önerir.

Swift'te Actor nedir ve ne zaman kullanılır?

Actor — thread güvenli referans türü. Derleyici, farklı bağlamlardan değiştirilebilir duruma eşzamanlı erişimi engeller. Birden çok görev tarafından erişilen durum yöneticileri, önbellekler ve hizmetler için Actor kullanın. Actor metotlarını çağırmak await gerektirir.

SwiftUI'de hangi Property Wrapper'lar kullanılır?

Başlıcaları: @State — yerel görünüm durumu; @Binding — sahiplik olmadan veri bağlantısı; @Published — ObservableObject'te değişiklik yayını; @StateObject — ObservableObject sahipliği; @EnvironmentObject — ortamdan bağımlılık. Özel sarmalayıcılar @propertyWrapper ile oluşturulur.

Protokol Odaklı Programlama nedir?

POP — sınıf kalıtımı yerine protocol + extension'ın davranışı tanımladığı bir paradigmadır. Bir tür birden çok protokole uyum sağlar ve uygulamalarını ücretsiz alır. Bu, kalıtım yerine kompozisyondur — daha esnek ve güvenlidir. Swift'in standart kütüphanesi (Equatable, Codable) POP üzerine inşa edilmiştir.

Swift'te enum diğer dillerdeki enum'dan nasıl farklıdır?

Swift'te enum ilişkili değerleri destekler — her durum farklı türlerde rastgele veri depolayabilir. Pattern matching (switch) ile birleştiğinde, durumlar, hatalar ve Domain-Driven Design için güçlü bir model sağlar. Optional ve Result, ilişkili değerlere sahip standart Swift enum'larıdır.

Özet

  • Struct vs Class — temel fark: değer türleri kopyalanır, referans türleri referansla iletilir. Struct kalıtımı desteklemez, class destekler. Apple varsayılan olarak struct'ı önerir.
  • Actor — derleyici düzeyinde thread güvenliği. İzole edilmiş değiştirilebilir durum, await ile erişim, manuel kilitler olmadan veri yarışlarına karşı koruma.
  • Property Wrappers — @Published, @State, @Binding ve @propertyWrapper ile özel. Tekrar eden kodu azaltır ve ek açıklama yoluyla niyeti açık hale getirir.
  • Generics — where kısıtlamaları ile tür güvenli fonksiyonlar ve türler. Soyutlamalar için Protocol + ilişkili tür. Swift'in standart kütüphanesi tamamen Generics üzerine inşa edilmiştir.
  • Protokol Odaklı Programlama — protokol extension'ı aracılığıyla davranış kompozisyonu. Varsayılan uygulamalar, sınıf kalıtımı olmadan kod yeniden kullanımına izin verir.
  • İlişkili değerlerle Enum — durumlar için güçlü bir model. Her durum benzersiz veriler depolar. Pattern matching, tüm durumların işlenmesini garanti eder.
  • Extension — enum dahil herhangi bir türe metot, hesaplanmış özellik ve protokol uyumu ekler. Orijinal bildirimi değiştirmeden kod modüler ve temiz kalır.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış