묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
- 
      
        
    해결됨[Lv.1] iOS 17 앱 개발 기초 - SwiftUI로 시작하기index와 indexSetfruitArray 를 delete하는 함수에서index가 아닌 indexSet과 remove(at:)이 아닌 remove(atOffsets:)를 사용하셨는데 왜 그렇게 하셨는지 궁금합니다! 
- 
      
        
    해결됨앨런 Swift Concurrency for Swift 6 (Part-2)18강 NSCache 예시 질문안녕하세요!18강 전체적으로 cache 에 값을 세팅하기 전후로 lock 이나 semaphore 등을 이용해서 GCD 에서 thread safe 를 구현하는 방법에 대한 예시를 들어준것 확인했습니다이때 removeAll() 의 앞뒤로는 따로 처리가 되어있지않아서, 정말 필요가 없어서 작성되어있지 않은건지, 아니면 단순 예시라서 여기까지는 적용하지 않은건지 궁금합니다func clearAll() { cache.removeAll() } 두번째로, 이건 주제와 좀 동떨어진 질문이긴한데요..! (혹시 강의 성격과 너무 벗어났다 싶으면 무시해주세요!)예시를 NSCache 로 들어주셨는데, NSCache 문서에 보면 캐시를 직접 잠그지 않고도 다양한 스레드에서 캐시에 항목을 추가, 제거 및 쿼리할 수 있다고 나와있는걸 확인했습니다.You can add, remove, and query items in the cache from different threads without having to lock the cache yourself즉, 문서를 통해 자체적으로 thread safe 하게 뭔가를 하고 있구나..를 유추할 수 있기 때문에 (내부적으로는 NSLock 을 사용하고 있긴하지만요) 이럴때는 저희쪽에서 @unchecked Sendable 만 사용해도 무방할까요?하지만 이런 문서 등을 확인하지 않는 이상 정확히 NSCache 가 thread safe 하게 뭔가를 처리한다는걸 확인할 수 없기 때문에, 예시처럼 @uncheked Sendable 명시와 동시에 자체적으로 semaphore 나 lock 을 걸어줘야하는건지..? 앨런님은 어떻게 생각하시는지 궁금합니다!감사합니다~ 
- 
      
        
    해결됨앨런 Swift Concurrency for Swift 6 (Part-2)Task 클로저 내 `non-Sendable` 값 타입 접근 시, 캡처 리스트가 정의된 Task 순서에 따른 컴파일러 에러 차이12강 16분 즘에, Task 의 클로저에 value type 의 프로퍼티를 캡처 리스트로 명시하면 아래와 같은 코드에서는 에러가 나지 않는다고 되어있습니다.struct ValueCounter { var value = 0 mutating func increment() -> Int { value = value + 1 return value } }  func test() { var valueCounter = ValueCounter()  Task { print(valueCounter.increment()) print(valueCounter.value) } Task { [valueCounter] in var newValueCounter = valueCounter print(newValueCounter.increment()) print(newValueCounter.value) } }하지만 제가 Xcode 26.0.1 에서 확인했을때는 해당 코드의 첫번째 Task 에서 다음과 같은 컴파일 에러가 발생했습니다Sending value of non-Sendable type '() async -> ()' risks causing data races이에 추가로 이것 저것 확인해보다가, 아래와 같이 캡처 리스트를 사용하는 Task 를 먼저 작성하면, 에러가 발생하지 않는것을 확인했습니다.// 캡처 리스트 사용하는 Task 순서 변경하니 정상 func test2() { var valueCounter = ValueCounter()  Task { [valueCounter] in var newValueCounter = valueCounter print(newValueCounter.increment()) print(newValueCounter.value) } Task { print(valueCounter.increment()) print(valueCounter.value) } }이와 같은 현상을 어떻게 설명할 수 있을지 궁금합니다.첫번째 예시의 두번째 Task 에서는 [valueCounter] in 으로 현재 값을 캡처하려고해도, 이미 첫번째로 정의된 Task 에서 valueCounter.increment() 를 호출하면서 다른 스레드 (편의상) 에서 값을 변경하고 있기 때문에, 동일 시점에 딱 한개의 쓰레드에서의 접근이 깨져서 이런 에러가 발생하는 걸까요? (그렇다기엔 에러 위치는 첫번째 Task 정의에서 떠서... 아닌가 싶기도하고요..)두번째 예시의 첫번째 Task 에서는 캡처 리스트로 값을 캡처해서 valueCounter.increment() 를 호출하고, 두번째 Task 는 valueCounter.increment() 를 하려고해도 이 시점에서 valueCounter 를 참조하고 있는건 이곳 뿐이기 때문에 (첫번째 Task 에서는 캡처해서 사용), 동일 시점에 딱 한개의 쓰레드에서의 접근이 보장되어서 에러가 발생하지 않는걸까요? 결과를 기준으로 나름대로 고민을 해봤는데, 어쨌든 다 추측이라서.. 혹시 이와 같은 현상을 어떻게 이해하면 될지 궁금합니다감사합니다. 
- 
      
        
    해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)확인 버튼 만들 때 폰트 색상 화이트 주는 위치 문의드려요.강의에 보면 확인버튼의 폰트 색상을 화이트로 줄 때 .background() 부분의 상단 또는 하단 측에 스타일을 줘도 된다고 하셨는데요. 하단 측에 .foregroundStyle(Color.white)를 주게 되면 확인 글자가 나타나지 않더라구요. 상단에만 줘야하는 것 아닌지 여쭤 봅니다. 
- 
      
        
    해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)Button(action: label:)이 강의와 달라요!강의를 보면 Button(action: {}, label: {})로 나오는데요. 저는 같은 것을 선택했는데 아래와 같이 나오면서 에러(?)가 뜹니다.제미나이에 물어봐도 제 수준에서는 답변이 이해가 가지 않아 질문 드립니다. 
- 
      
        
    해결됨앨런 Swift Concurrency for Swift 6 (Part-1)Task 의 default 우선순위 문의 (utility vs medium)안녕하세요 3강 19:34 쯤에 Task 의 default 우선순위를 utility 로 말씀주셨는데, 제가 확인해봤을때는 medium 인 듯해서.. medium 이 맞을까요?Task.detached { print(Task.currentPriority) } // TaskPriority.mediumTaskPriority 의 구현부를 볼때도 default 가 medium 으로 되어있는것 같구요! @available(*, deprecated, renamed: "medium") public static let `default`: TaskPriority별로 중요한건 아니구, 나중에 한번 더 언급해주실거라고 하셔서 1부를 끝까지 들어봤는데, 별도로 말씀주시는 내용이 없는 듯 하여 가볍게 질문드립니다~감사합니다 
- 
      
        
    해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)HStack과 VStack에서 alignment와 spacing 방향이 이해가 잘 안갑니다.스킬 창 아래 부분은 HStack에 VStack(앉아, 엎드려, 하우스)과 VStack(손, 코) 두개의 VStack 구조로 되어 있잖아요.여기서 alignment와 spacing 방향이 너무 혼동됩니다. 처음에 간단한 구조는 이해하는 것 같았거든요. 살짝 구조가 복잡해지니까 혼동됩니다. 우선 제가 이해하고 있는 부분은 아래와 같습니다.HStack은 수평 구조이기 때문에 alignment는 top, center, bottom이고 spacing은 수평 간격이 조정되고 VStack은 수직 구조이기 때문에 alignment는 leading, center, tailing이고 spacing은 수직 간격이 조정 되는 것이 맞을까요?혹시 맞다면 이 정도만 이해하고 있으면 될까요?이 부분의 대한 설명 좀 부탁드려도 될까요? 
- 
      
        
    미해결[Lv.3] 실전 네트워크 통신 - SwiftUI Combine, Async/Await@Published의 용도안녕하세요이번 실전 네트워크 통신 강의를 들으며 ViewModel을 만들 때 1번 방법이 아닌 2번 방법으로 만들 수 있다는 사실을 알게되었습니다. 앞쪽 강의에서 기존 1번 방식에서는 변수 생성 시 @Published 를 붙여야했지만, 2번 방식처럼 @Observable을 사용하면 @Published를 붙이지 않아도 된다고 하셔서 결국 위의 두 코드는 같은 기능을 한다고 이해를 했습니다. 그런데 이번 강의에서 아래와 같이 @Published를 사용하여서, 이 부분이 이해가 잘 가지 않습니다 혼자 고민해본 결과로는, - count 변수: 단순히 값을 읽고 쓰는 용도- textFieldID: 퍼블리셔(특정 시간/조건에 따라 값을 방출하는..?)로 사용 위의 용도 차이이다. 그렇다면 기존 방식에서 @Published를 모두 붙여야했던 이유는 무엇인지..? 라는 질문이 또 생기는 것 같습니다. 답변 주시면 감사하겠습니다!! 
- 
      
        
    해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)modifiers 창이 안보여요.xcode 26.0.1 사용 중인데요.inspectors 창은 열려 있는데요.modifiers 창이 없고 이미지와 같이 3개만 보여요.이럴 땐 어떻게 해야할까요? 
- 
      
        
    미해결앱 개발 기초부터 실전까지 하나로 끝내는 Swift & iOS 마스터 클래스430강 modularization안녕하십니까? 강사님명절은 잘보내셨는지요?실습중에 오류가 나는 부분이 있어 질문 드립니다.430강 shiny day를 모듈화시키는 강의를 실습하던중에 오류가 나서 질문 드립니다.ShinyModel, ShinyService, ShinyFormatter를 패키지화 시켰고,access level도 수정했습니다.그런데도 오류가 납니다. Xcode 26에서 코딩했고, 오류부분의 일부분은 chatgpt도움을 받아 수정하였습니다.혹시 몰라 전체 소스를 이메일로 보내드립니다.바쁘시더라도 확인 부탁드립니다. 
- 
      
        
    해결됨앨런 Swift Concurrency for Swift 6 (Part-1)18강 자식 작업의 메타데이터 상속 관련 강의 자료 문의안녕하세요~18강 8:35 쯤 강의자료에 자식 작업은 부모작업의우선순위 실행중인액터로컬변수를 상속한다고 되어있는데 이때 실행중인 액터에 취소선이 그어져있는 이유가 있을까요?혹시 의미가 있는건지...궁금합니다감사합니다 
- 
      
        
    해결됨앨런 Swift Concurrency for Swift 6 (Part-1)withCheckedContinuation 에서 resume 호출의 안정성 보장 질문안녕하세요~ 강의 잘 보고 있습니다. withCheckedContinuation 에서 resume 호출에 대해 질문이 있습니다.11강의 12:56 쯤에서 'withCheckedContinuation 에서는 resume 을 두번 호출해도, runtime 에서 알아서 두번째 resume 되는걸 체크해서 크래시가 발생하지 않게 해준다고 공식문서에서 나와있다. 즉, 안전하다' 라고 설명을 해주시는데요 (12강에서도 Checked 는 안전하다고 나와있구요),제가 확인을 해보았을때는 withCheckedContinuation 에서도 resume 을 두번 호출하면 런타임 에러가 발생하는 것을 확인했습니다.다만 CheckedContinuation과 UnsafeContinuation 의 케이스별 에러 로그 / 콘솔 로그가 조금 달랐습니다.애플 문서에서는 checked continuation 만이 오용(misuse)에 대한 detect 및 diagnose 를 제공한다고 되어있는데요, 이를 통해 제가 유추할 수 있는건 withCheckedContinuation 은 런타임에 "안전" 하다기 보다는, resume 을 잘못 사용했을때 좀 더 자세한 에러 로그(여러번 호출시) 및 콘솔 로그(미호출시)를 통해 개발자가 resume 을 한번만 올바르게 호출할 수 있도록 도와주는 역할을 한다는 것이었습니다.혹시 withCheckContinuation 에 대해 강의해서 설명해주신 "안전" 의 의미와, "두번째 resume 되는걸 체크해서 크래시가 발생하지 않게 해준다" 의 문서 레퍼런스를 알 수 있을까요?참고로 체크한 코드는 다음과 같습니다func fetchGreeting(completion: @escaping (Result<String, MyError>) -> Void) { completion(.success("hello")) }  enum MyError: Error { case bye }  func asyncFetchGreeting() async throws -> String { let greeting = try await withCheckedThrowingContinuation { continuation in fetchGreeting { greeting in continuation.resume(with: greeting) // 📍 resume 호출부 } } return greeting }   Task { do { let greeting = try await asyncFetchGreeting() } catch { } }감사합니다. 
- 
      
        
    미해결[Lv.2] SwiftUI 중급 - Core Data와 SwiftData로 앱 완성하기Sorted, Filter, Map - UserViewModel 부분 오류 발생강의 관련된 질문은 언제나 환영입니다 😄코드 관련 상세하게 작성해주시면 더 좋아요! (상세코드를 붙여넣기 해주세요)마크다운을 사용해서 편리하게 글을 작성하세요먼저 유사한 질문이 있었는지 먼저 검색 해보는 습관~인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요Protocol requires property 'objectWillChange' with type 'Self.ObjectWillChangePublisher' (Combine.ObservableObject.objectWillChange)Initializer 'init(wrappedValue:)' is not available due to missing import of defining module 'Combine'이렇게 두개의 오류가 뜨는데. 영상을 봐도 해당 코드와 다른게 없어서 질문드립니다. 혹시 어떤 부분이 문제일까요? 
- 
      
        
    해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)showAlert 변수 mvi 패턴에서의 사용법안녕하세요 애구마님!앱 클라이언트 개발 시, 보통 showAlert 같은 UI 동작을 제어하는 변수는 화면(Screen)에서 직접 관리하는 경우가 많다고 들었어요!그런데 만약 진행 할 프로젝트에 MVI 패턴을 적용한다면, 이 showAlert 같은 UI 상태들은 별도의 상태(State) 클래스에서 관리하는 게 맞을까요?즉, MVI 패턴에서는 showAlert를 포함한 모든 UI 상태를 상태 클래스(State)로 중앙 집중 관리하고, 사용자 동작은 Intent로 받아서 상태를 변경하는 방식으로 관리하면 되는 건지 궁금합니다.이 부분에 대해 조언 해주시면 정말 감사드리겠습니다! 
- 
      
        
    해결됨앱 개발 기초부터 실전까지 하나로 끝내는 Swift & iOS 마스터 클래스개발버전 release 버전 실습 중 오류-부탁드립니다.안녕하세요 강사님섹션 39. 413강을 실습하던중 오류가 있어서 문의 드립니다,위와 같이 오류가 뜹니다.target이 dev는 이상없이 잘 실행됩니다. 
- 
      
        
    해결됨Part1: 진짜 왕초보 iOS 배우기(SwiftUI, SwiftData, 2024)swift vs swiftUI안녕하세요. Swift에 입문한 주진성입니다.혼자 AI를 통해 학습하던 중 Xcode와 Mac 키보드 단축키 적응에 어려움을 느껴 좋은 강의를 찾게 되었습니다. 정성껏 쉽게 설명해주시는 강의 덕분에 많은 도움을 받고 있습니다.다름이 아니라, 강의 제목('Swift vs. SwiftUI')에 대해 궁금한 점이 있어 문의드립니다. 보통 'JavaScript vs. React', 'Java vs. Spring Boot'라고 표현하지 않는 것처럼, 'Swift & SwiftUI'가 더 정확한 표현이 아닐까 하는 생각이 들었습니다.혹시 다른 특별한 이유가 있는지 여쭤보고 싶습니다. 
- 
      
        
    미해결야곰의 스위프트 기본 문법 강좌강의+교재 질문) didSet 실행되지 않음안녕하세요 야곰님 야곰님의 스위프트 교재도 함께 보고있습니다. [ didSet 감시자 코드블록 내부에서 oldValue 값을 참조하지 않거나 매개변수 목록에 명시적으로 매개변수를 적어 (didSet(oldValueName) 주지 않으면 didSet 코드 블록이 실행되지 않습니다. ]NOTE 내용에서 발췌한 부분인데요 아무리 .. 테스트 해 보려고해도 didSet은 계속 호출되는데 어떻게 해야 학습해 볼 수 있을까요 ? 
- 
      
        
    미해결[Lv.1] iOS 17 앱 개발 기초 - SwiftUI로 시작하기NavigationBarItems DeprecatedNavigationbarItem -> .toolbar로 바뀐 코드가 궁금합니다. 
- 
      
        
    해결됨앱 개발 기초부터 실전까지 하나로 끝내는 Swift & iOS 마스터 클래스메모의 그룹을 클릭할때마다 항목이 틀리게 나옵니다.안녕하세요. 강사님메모앱을 실습하던중에 질문 사항이 있어 이렇게 글을 올립니다.그룹을 선택하면 그 그룹에 속한 메모들이 제대로 보이긴 한데, 그게 때에 따라서 틀려진다는게 이해할 수가 없어서 질문드립니다.제가 어디서 잘못 코딩을 했는지 그 부분을 찾지를 못했습니다.그래서 이미지라도 올립니다. 위 그림 처럼 같은 그룹인데도 그룹을 클릭할때마다 메모 리스트의 항목이 틀리게 나옵니다.한번 봐주시면 감사하겠습니다. 
- 
      
        
    해결됨앨런 Swift Concurrency for Swift 6 (Part-1)참고 코드 자료 7-StructuredConcurrency(102, 103줄) 오타?자주하는 질문 모음링크: https://pointed-earwig-996.notion.site/Swift-Concurrency-for-Swift-6-Part-1-22eecb0b83154ac28c7c66446f6e54e1?pvs=4 자주하는 질문을 먼저 확인 부탁드리며, 질문은 최대한 구체적으로하셔야 빠르게 답변드릴 수 있습니다. [질문 예시](1) 몇강, 몇초의 내용이 잘 이해가 안갑니다. (제가 적어놓은 강의 번호 "10강, 7분 강의 내용 중에... " )(2) 강의자료 몇페이지의 내용이 잘 이해가 안갑니다.(3) 정확하게 어떤 포인트에 대한 내용이 이해가 안갑니다. 다시 설명해주실 수 있나요? 동시성 강의 코드파일 7번(7-StructuredConcurrency(102, 103줄) ) 내용인데요전체코드func fetchAsyncLetTwoImages() async throws -> (UIImage, UIImage) { let start = Date() /// 구조적 동시성 작업의 생성 (하위 작업의 생성) async let image1 = try await fetchImage(num: 1) async let image2 = try await fetchImage(num: 2) let images = try await (image1, image2) print(Date().timeIntervalSince(start).formatted(.number.precision(.fractionLength(1)))) return images } 이렇게 되어 있는데 async let image1 위치에서 fetchImage(num:1)의 값을 기다리는 형태입니다. 아마도 이렇게 바뀌는게 맞지 않나 싶습니다. /// 구조적 동시성 작업의 생성 (하위 작업의 생성) async let image1 = fetchImage(num: 1) async let image2 = fetchImage(num: 2) 그런데 위의 코드는 순서대로 결과값을 받는 경우이고 아래 코드는 동시에 돌려서 빨리 나오는 결과값이 먼저 반영되나 싶었는데 그것도 애매하네요.A코드 /// 구조적 동시성 작업의 생성 (하위 작업의 생성) async let image1 = try await fetchImage(num: 1) async let image2 = try await fetchImage(num: 2)B코드 /// 구조적 동시성 작업의 생성 (하위 작업의 생성) async let image1 = fetchImage(num: 1) async let image2 = fetchImage(num: 2)실제로 두 코드를 돌려보니 A코드는 4.8 ~ 3.2초 걸렸는데 대략 평균적으로 3.6초 걸리고, B코드는 4.2 ~ 2.5초 걸려서 대략 평균적으로 3.3초 정도 걸리더라구요.image1과 image2는 try await Task.sleep(for: .seconds(2))가 걸려 있어 각각 2초씩이어서 동시에 돌아가서 결과를 받으면 2초 조금 넘을 것 같고 순서대로 받으면 4초 조금 넘을 것입니다. 그런데 두 코드 모두 4초가 안걸리는 경우가 많았다는 점에서 동시성이 적용되는 것 같습니다. 그런데 어떤 속도의 차이가 있을까 했는데 별 차이가 없는 느낌이기도 합니다.Claude에게 물어보니 A코드가 동시성의 효과를 보지 못한다고 하지만 속도 면에서 B코드가 특별히 빠르다고 단정하기도 애매해서요. 오타라고 생각되지만 A코드는 어떤 의미가 있을까 궁금합니다. 
