Một số @Attributes mạnh mẽ trong swift
Hiểu và học cách sử dụng các @Attribute đúng và hiệu quả hơn

@escaping

    Thường được sử dụng khi closure là tham số của function. Khi khai báo một optional closure như một property, mặc định nó đã được escaping.

class Service {
    var closure: @escaping (() -> Void)? //error: closure is already escaping in optional type argument
}

    Escaping closure có thể được lưu trữ để sử dụng sau này:

class Service {

    var closure: (() -> Void)?

    func storageExample(with completion: @escaping (() -> Void)) {
        closure = completion // Stored for later use
    }
}

    Hoặc nó có thể được thực thi sau khi function kết thúc:

class Service {
    func asyncExample(with completion: @escaping  (() -> Void)) {
        DispatchQueue.global().async { // Excute escaping closure ayncally
            completion()
        }
    }
}
view raw

@unknown

    @unkown được giới thiệu với @frozen@nonfrozen enum. 1 non-frozen enum có thể tăng thêm các case mới sau này. Ví dụ, hiện tại UILayoutConstraintAxis chứa 2 trục:

enum UILayoutConstraintAxis: Int { 
  case UILayoutConstraintAxisHorizontal = 0
  case UILayoutConstraintAxisVertical = 1 
}

    Nó có thể có thêm case axisZ sau này:

enum UILayoutConstraintAxis: Int { 
  case UILayoutConstraintAxisHorizontal = 0 
  case UILayoutConstraintAxisVertical = 1
  case UILayoutConstraintAxisZ = 2
}

    Để tránh bị lỗi khi compile: error: switch must be exhaustive

    Chúng ta implement switch với thuộc tính @unknown:

switch axis {
case .UILayoutConstraintAxisHorizontal:
    print("")
case .UILayoutConstraintAxisVertical:
    print("")
@unknown default:
    print("")
}

@propertyWrapper

    Khi apply một property wrapper cho một property của 1 class, struct, hoặc enum, nó wrap quyền truy cập vào thuộc tính thông qua một instance của kiểu wrapper.

    Wrapper phải difine 1 wrapperValue. Ví dụ dưới đây trims khoảng trắng và newline từ string:

@propertyWrapper
struct WhitespaceTrimmable {
    private(set) var value: String = ""

    var wrappedValue: String {
        get { value }
        set { value = newValue.trimmingCharacters(in: .whitespacesAndNewlines) }
    }

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue
    }
}

    Để sử dụng:

struct Service {
    @WhitespaceTrimmable var title: String
}

let service = Service(title: "Title    ")
print(service.title) // Title
view raw

    Property wrapper có thể chứa tham số làm giá trị mặc định:

struct Service {
    @WhitespaceTrimmable(wrappedValue: "Default title") var title: String
}

var service = Service()
print(service.title) // Default title

    Để truy cập wrapped property trực tiếp, sử dụng _ như một prefix name:

struct Service {
    @WhitespaceTrimmable(wrappedValue: "Default title") var title: String

    func accessTitle() {
        print("title: \(_title)") //Default title
    }
}

@available

    Dùng để chỉ ra các dòng code chỉ available trong version swift hoặc os version cụ thể. Ví dụ, để sử dụng thành phần UICollectionView mà chỉ available trên iOS 13+:

public struct CollectionViewCellProvider {
    @available(iOS 13, *)
    public static func compositionalCell() {
        // compositional collection view cell
    }

    public static func collectionCell() {
        // collection view cell
    }
}

@discardableResult

    Dùng để bỏ qua result của function mà không bị complie warning.

class ParentViewController: UIViewController {
    override func viewDidLoad() {
        presentViewController() // Result of call to 'presentViewController' is unused
    }

    func presentViewController() -> UIViewController {
        return UIViewController()
    }
}

    Để tắt warning này, sử dụng @discardableResult:

class ParentViewController: UIViewController {
    override func viewDidLoad() {
        presentViewController() // No Xcode complains!
    }

    @discardableResult
    func presentViewController() -> UIViewController {
        return UIViewController()
    }
}

@UIApplicationMain

    Đây có lẽ là 1 attribute được biết đến nhiều nhất, nó nằm trong AppDelegate.swift để chỉ ra main entry point của ứng dụng iOS.

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
}

Tổng kết

    Swit tiếp tục thêm vào những @attribute trong những version khác nhau. Hiểu và sử dụng chúng đúng và hiệu quả có thể khiến code clean hơn và app performance tốt hơn. Tất cả code ở trên có thể tìm thấy ở trong git repo này: GitHub repo

    Nguồn tham khảo: 10 Powerful @Attributes in Swift

Nguồn: Viblo

Bình luận
Vui lòng đăng nhập để bình luận
Một số bài viết liên quan