WWDC의 Demystify SwiftUI를 정리한 내용입니다.SwiftUI는 선언적UI로서 고수준의 앱이 원하는 것을 Describe하면 SwiftUI가 이를 구현하는 방법을 정확히 결정.대부분의 경우 잘 작동하지만, 예상하지 못한 동작을 하는 순간은 생겨나는데,이런 순간에 원하는 결과를 얻기 위해 SwiftUI가 뒤에서 무엇을 하는지 이해하는 것이 도움이 됨. SwiftUI가 코드를 볼때 무엇을 보는가Identity: SwiftUI가 앱의 여러 업데이트에서 element를 동일하거나 별개로 인식하는 방법Lifetime: SwiftUI가 시간이 지남에 따라 View와 데이터의 존재를 추적하는 방법의존성: SwiftUI가 인터페이스를 업데이트해야하는 시기와 이유를 이해하는 방법위 세가지 개념이 Swift..
https://developer.apple.com/documentation/swift/collection/count-4l4qk Collection의 Element를 세어주는 count의 복잡도는 기본적으로 O(n) 연산. RandomAccessCollection을 준수하는 경우 O(1) 연산. Collection이 비어있는지 여부를 체크할 때는 Collection.count == 0 으로 체크하는 것보다, Collection.isEmpty 로 체크하는 것이 더 좋음. if someArray.count == 0 { // ❌ ... } if someArray.isEmpty { // ⭕️ ... }
Generic 모델링에서 시작합니다. 아래와 같은 Animal 프로토콜이 있을 때, 이를 사용하는 Farm struct의 메서드에서 Animal의 Concrete 타입으로 대체될 타입파라미터적합성을 따르도록 적용할 수 있습니다. protocol Animal { associatedtype Feed: AnimalFeed func eat(_ food: Feed) } struct Farm { func feed(_ animal: A) { // ... } } 혹은 아래처럼 후행 where절에서 프로토콜 적합성을 지정할 수 있습니다. where절은 디테일하게 requirement와 타입 관계를 작성할 수 있게 해줍니다. struct Farm { func feed(_ animal: A) where A: Animal {..
프로토콜 extension 프로토콜 자체를 확장하여 프로토콜 member의 기본 구현을 제공할 수 있습니다. extension Localizable { static var supportedLanguages: [Language] { return [.english] } } 여기서는 supportedLanguages의 기본 구현으로 Localizable을 확장합니다. Localizable을 준수하는 각 타입은 이제 해당 구현에 액세스할 수 있으므로 자체 정의할 필요가 없습니다. struct Image: Localizable { // no need to add `supportedLanguages` here } 위까지는 코드의 모든 유형이 구현할 수 있는 프로토콜로 작업했습니다. 특정 class에 의해서만 준수되..
https://developer.apple.com/videos/play/wwdc2022/110352/ Generic 모델링에 some/any를 적용하는 방법을 설명한 WWDC22 영상입니다. Farm을 시뮬레이션 하기 위한 예시. 추상화 도구들을 사용하기 전의 Concrete 타입의 예시부터 작성. Concrete 타입으로 먼저 모델링 Cow 구조체는 Hay(건초) 타입의 매개변수를 받는 eat()이라는 메서드가 존재하고, Hay 구조체는 Alfalfa 종류의 작물을 재배하기 위한 grow()라는 static 메서드가 존재. Alfalfa 구조체는 Alfalfa인스턴스에서 Hay를 수확할 수 있는 harvest() 메서드가 존재. Farm 구조체는 Cow에게 먹이를 줄 수 있는 feed() 메서드가 있음..
Building ifelse 아래에서는 R이 사용하는 통계 프로그래밍 언어와 같은 ifelse() 문을 구현. // R ifelse(condition, valueTrue, valueFalse) Swift 삼항 연산자 condition ? valueTrue : valueFalse 과 동일한 작업을 수행. 플레이그라운드에 아래 코드를 작성. func ifelse(condition: Bool, valueTrue: Int, valueFalse: Int) -> Int { if condition { return valueTrue } else { return valueFalse } } let value = ifelse( condition: Bool.random(), valueTrue: 100, valueFalse: ..
LLVM 프로젝트는 모듈식의 재사용 가능한 컴파일러와 툴체인의 집합. LLVM이라는 이름은 약자가 아니며 그것이 오픈소스 프로젝트의 풀 네임. (LLVM은 Swift 뿐만 아니라 Kotlin, Rust 등에서도 사용중) Swift 툴체인의 핵심은 Swift 컴파일러이며 소스 코드(.swift)를 실행 파일에 연결할 수 있는 object코드(.o)로 변환하는 역할을 함. LLVM 컴파일러 인프라에서 실행되는 데이터 흐름. Parse(구문 분석): Swift 소스 코드는 먼저 토큰으로 Parse되고 Abstract Syntax Tree(AST. 추상 구문 트리)에 입력됨. 이것은 각 표현식이 노드인 트리라고 생각할 수 있음. 노드는 또한 소스 위치 정보를 가지고 있어서 error가 감지되면 노드는 문제가 발..
이번 WWDC23의 Expand on Macros 세션의 전반부 정리. (https://developer.apple.com/wwdc23/10167) Swift Macro는 컴파일러를 수정하지 않고 Swift 패키지에 배포할 수 있는 방식으로 boilerplate코드를 제거하고 Swift에 고유 언어기능을 추가 가능. 4가지 목적 1. Macro를 사용할 때 매우 명확해야 할 것. 2종류의 Macro. FreeStanding Macro: 코드에서 다른 항목을 대신함. #(pound)기호로 시작 Attached Macro: 코드 선언에서 attribute로 사용됨. @(at)기호로 시작 Swift는 이미 #과 @를 사용해서 특정 컴파일러 동작을 나타내고 있지만, Macro로 이를 확장할 수 있게 만듦. #이..
What’s new in Swift - WWDC23 - Videos - Apple Developer Join us for an update on Swift. We'll show you how APIs are becoming more extensible and expressive with features like parameter packs... developer.apple.com if/else문의 향상 복잡한 조건을 기반으로한 let 변수를 초기화하려면 아래와 같은 복잡한 삼항 표현식이 나올수도 있습니다(있나!?). let bullet = isRoot && (count == 0 || !willExpand) ? "" : count == 0 ? "- " : maxDepth (R1, R2) func evalu..
Xcode 14.3이 릴리즈되면서 Swift 5.8도 업데이트되었습니다. 변경점들을 간단하게 정리해봅니다. Function back deployment (SE-0376) @backDeployed(before:) attribute를 통해 이전 버전의 프레임워크에서 새 API를 사용할 수 있게 해줍니다. 함수에 대한 코드를 앱의 바이너리에 작성 후 런타임 시 검사하여 수행됩니다. 사용자가 적절한 새 OS를 사용하는 경우 시스템 자체 버전의 함수가 사용되고, 아닌 경우 앱 바이너리에 복사된 버전에 대신 사용됩니다. 단, @backDeployed는 함수, 메서드, 서브스크립트, 계산프로퍼티에만 적용됩니다. 당연하게도 만능으로 새 기능을 이전 OS에서 쓸 수 있게 한다던가 하는건 아닌거죠. 아래는 예시입니다. @..
dynamicMemberLookup은 class, struct, enum, protocol에 적용하여 런타임에 dot(.) 문법으로 접근할 수 있도록 해주는 편리한 기능입니다. dynamicMemberLookup을 사용하려면 subscript(dynamicMember:)를 구현해주어야 합니다. @dynamicMemberLookup struct Person { var firstName: String var lastName: String subscript(dynamicMember key: String) -> String { switch key { case "fullName": return "Hey, \(lastName) \(firstName)!!!" default: return "nope!!!" } } } ..
Key-Value Coding (KVC) Key-Value Coding은 객체의 프로퍼티를 Key-value 쌍으로 접근할 수 있도록 해주는 Objective-C 문법입니다. KVC를 사용하면 속성의 이름을 문자열로 참조하여 런타임에 동적으로 객체의 프로퍼티 값을 설정하거나 읽을 수 있습니다. Swift에서도 사용할 수 있지만, Objective-C 런타임에 의존하기 때문에 프로퍼티 선언 시 앞에 @objc 어노테이션을 붙여줘야 하며, NSObject의 서브클래스에서만 사용이 가능합니다. class Person: NSObject { // NSObject 서브클래스 @objc var name: String? // @objc 어노테이션 } 위와 같이 선언된 클래스의 프로퍼티는 아래처럼 KVC로 접근이 가능합..
Key-Value Observing(KVO)은 다른 객체의 property 변경에 대해 객체에 알리는 데 사용하는 코코아 프로그래밍 패턴입니다. Model과 View 사이와 같이 앱의 논리적으로 분리된 것 사이의 변경 사항을 전달하는 데 유용합니다. willSet, didSet과 유사하지만 KVO는 객체 외부에서 property변경을 관찰하는 데 사용된다는 차이점이 있습니다. NSObject를 상속받은 클래스에서만 Key-Value Observing을 사용할 수 있습니다. Key-Value Observing을 위해 Observe할 property 앞에 @objc attribute와 dynamic modifier를 붙여주어야 합니다. class Almond: NSObject { // NSObject를 상속..
코딩테스트를 풀이할 때 유용했던 XOR 연산자(^)입니다. XOR 연산자는 같은 수를 2번 연산했을 때 없어지는 속성이 있습니다. 게다가 그 같은 수 2번의 위치는 꼭 붙어있지 않아도 상관이 없습니다. 3^5^5 // 3 3^5^5^3 // 0 3^3^5 // 5
코딩테스트 풀이할 때 유용했던 String 생성자입니다. 입력한 value를 N진수(radix)로 변환해줍니다. 11진수 이상일 때 uppercase로 반환해주는 parameter도 제공합니다. 아래는 예시입니다. String(10, radix: 2) // 1010 String(999999, radix: 16) // f423f String(999999, radix: 16, uppercase: true) // F423F