분류 전체보기

    [Swift] Closure

    [Swift] Closure

    소들이님 클로져 글 + 개인적으로 공부한 내용 정리한 내용입니다 :) 참고 - https://babbab2.tistory.com/81 클로져(Closure) Named Closure ⇒ 우리가 알고있는 함수 그 자체 Unnamed Closure ⇒ 우리가 알고있는 클로져! 클로져 표현식 → Parameter Name도 존재하고, Argument label은 존재하지 않는다. {(파라미터) -> 리턴타입 in 코드 블럭 } // 실제 예 let 클로져 = { (age: Int) -> String in return "내 나이, \(age)" } 클로져는 1급 객체이다 변수나 상수에 대입이 가능하다. 함수의 파라미터 값으로 클로져를 전달할 수 있다. func closureExample(completionHan..

    [Swift] Enumeration(열거형)

    [Swift] Enumeration(열거형)

    Enumeration(열거형) 원시 값이 있는 열거형 아래의 경우는 원시 값을 지정해주지 않고, 그냥 Int만 채택해주어도 알아서 원시값이 설정된다. enum SoccerPlayer: Int { case attacker = 0 case defenser = 1 case midfielder = 2 } 연관 값이 있는 열거형 아래와 같이 default로 존재하는 연관 값을 가진 case, default가 없는 연관 값 case도 존재한다. enum TypeName { // default 값을 넣을 수 있다. case caseName(type: String = "NameString") case caseNameTwo(typeNumber: Int) } 아래와 같이 switch문으로 연관 값을 처리할 수 있다. le..

    [iOS] Gesture recognizer, Touch event handling

    [iOS] Gesture recognizer, Touch event handling

    제스처를 구현하는 방법은 두 가지가 존재한다. Gesture Recognizer UIView's Touch Event Handling UIView's Touch Event Handling 터치 이벤트와 관련된 함수들이다. touchesBegan 터치가 일어날 때 불려지는 함수이다. touchesMoved 터치를 움직일 때마다 불려지는 함수이다. touchesEnded 터치가 끝날 때 불려지는 함수이다. touchesCancelled 위의 3가지의 이벤트가 발생도중에 갑자기 Alert이 발생한 경우 불려지는 함수이다. 아래의 예와 같이 viewcontroller 안에 아무곳에서 override를 하면된다. override func touchesMoved(_ touches: Set, with event: U..

    [Swift] mutating

    [Swift] mutating

    mutating 키워드 struct안에 있는 프로퍼티 값을 변경시킨다고 무조건 mutating 붙히는 게 아니다! 아래와 같은 경우에만 mutating 키워드를 붙힌다. 변경되는 값이 값 타입일 경우에만 mutating을 붙힌다. 만약 변경되는 값이 참조타입이지만 주소값이 변경이된다면 mutating 을 붙힌다.(아래의 예들을 통해서 이해를 해보자) 아래 예의 경우, 변경되는 값은 참조타입인 Array 속 프로퍼티가 변하는 것이기에 mutating을 붙히지 않아도된다.(elements가 변해도 array 프로퍼티가 참조하고 있는 Array() 객체의 주소 값이 변하는 것은 아니기에!) // 가능하다. class Array { var elements = [1,2,3,4,5] } struct TestStru..

    [Swift] 값 타입, 참조 타입, let, var

    [Swift] 값 타입, 참조 타입, let, var

    let VS var struct 구조체의 경우, 그 안의 프로퍼티 값을 변경하려면 무조건 var로 인스턴스를 생성해야된다. 단, 프로퍼티는 Struct 안에서 var로 선언되어있어야된다. struct Struct { var string = "happy" } let structInstance = Struct() structInstance.string = "sad" // error class 클래스의 경우, 그 안의 프로퍼티 값을 변경할 때, var나 let이나 상관없이 인스턴스를 생성해주면된다. 단, 프로퍼티는 클래스 안에서 var로 선언되어있어야된다. class Class { var string = "happy" } let classInstance = Class() classInstance.string ..

    [iOS] 의존성 관리 도구(Package Manager)

    [iOS] 의존성 관리 도구(Package Manager)

    다양한 의존성관리 도구 CocoaPods Dynamic, Static 라이브러리를 모두 지원 대부분의 라이브러리가 지원한다. 여러 개의 pod들의 종속성을 확인하기가 쉽다. 종속된 pod들을 매번 build해야된다. → 시간이 많이 든다. Carthage Dynamic, Static 라이브러리를 모두 지원 프레임워크를 한번만 빌드하면 되므로, 빌드 속도가 매우 빠르다. 어떤 오픈소스를 쓰고있는 지 보기 편한다. 여러 개의 pod들의 종속성을 확인하기가 쉽다. 새로운 패키지를 가져다 쓸 때마다 프레임워크를 추가해 줘야하는 번거로움이 존재한다(추가할 때 시간이 많이 걸린다.) 설치하려면 Ruby gem 필요 (맥은 ruby가 내장되어 필요x) Swift Package Manager (SPM) Dynamic,..

    [Swift] 함수 return에대한 고민

    [Swift] 함수 return에대한 고민

    함수의 return에 대한 고민 함수의 바디에서 return을 만나면 그 이후는 진행하지도 않고 끝난다! // Code after 'return' will never be executed! // 항상 true를 return한다! func returnBool(x: Int) -> Bool { return true if x > 5 { return true } return false } 아래와 같은 예에서도 만약 x가 5보다 클 경우, if문을 만족하므로 return true를 하고 함수를 끝낸다! func returnBool(x: Int) -> Bool { if x > 5 { return true } return false } print(returnBool(x: 6)) // true for 문 속 guard문..

    [Swift] Error Handling

    [Swift] Error Handling

    Error Handling 오류 정의 정의/ throw / try do - catch까지 사용한 예‼️⁉️ throws를 하는 함수를 사용하려면 무조건 앞에 try를 붙혀주어야된다. // enum형으로 error타입명 정의 enum DataError : Error { // Error 프로토콜을 구현한 것은 오류 타입으로 사용하라는 일종의 가독성 표시 case overSizeYear case incorrectData(part: Int) } // 오류가 나는 조건을 throws와 함께 배치 -> throw 문 추가 func getNextYearAndThrows(paramYear: Int) throws -> Int { guard paramYear = 0 else { throw DataError.incorrec..

    [Swift] 프로퍼티 옵저버

    [Swift] 프로퍼티 옵저버

    프로퍼티 옵저버(Property Observer) 프로퍼티 값의 변화를 관찰하는 것! 누군가 프로퍼티에 값을 설정할 때 작동한다. 저장 프로퍼티에 추가할 수 있다. 두 가지의 옵션이 존재한다. willSet → 값이 저장되기 전에 호출이된다. didSet → 새 값이 저장된 직후에 호출이된다. willSet 값이 지정되기 직전에 새로 저장될 값이 파라미터로 전달이된다. 아래와 같이 구현이 가능하다. var name: String = "Unknown" { willSet(newName) { print("현재 이름 = \(name), 바뀔 이름 = \(newName)") } } 또한, 파라미터 이름을 생략하여 아래와 같이도 설정할 수 있다. var name: String = "Unknown" { willSet..

    [Swift] 상속(Inheritance)

    [Swift] 상속(Inheritance)

    상속(Inheriatance) → 클래스만 상속이 가능하며 단일 상속만 가능하다! 서브 클래싱(subclassing) → 기본 클래스를 기반으로 새로운 클래스를 만드는 작업이다. 상속 받는 클래스 → 서브 클래스 상속 해주는 클래스 → 슈퍼 클래스 예를 통하여 이해해보자. 아래와 같이 Human 클래스가 존재한다. class Human: Hashable { var name: String? var age: Int? } 그리고, Human 클래스를 상속 받는 Teacher 클래스가 존재한다. Teacher 클래스는 Human 클래스의 멤버들을 모두 가지면서, 추가적으로 더 필요한 멤버들을 가진 클래스이다. class Teacher: **Human** { var subject: String? } “Teache..

    [Swift] Lazy (지연 저장 프로퍼티)

    [Swift] Lazy (지연 저장 프로퍼티)

    Lazy (지연 저장 프로퍼티) 처음 사용되기 전까지 초기값이 계산되지 않는 프로퍼티 항상 변수로 선언되어야한다. 처음에는 값이 없다가 초기화가 되면 값이 생기게 되기에 struct와 class에서만 사용이 가능합니다. computed property와는 사용을 할 수가 없다. lazy는 호출된 처음에 메모리에 값을 올리고 계속해서 그 값을 쓴다. 반면 computed property는 호출될 때마다 지속적으로 연산을 진행해야되므로. closure내에서의 self를 통해서 접근이 가능하다. closure내에서의 self를 통해서 접근이 가능하다. 아래와 같은 코드를 통하여 위의 말을 이해해보자.(연산 프로퍼티 아니다!) class Person { var name:String lazy var greetin..

    [Swift] Optional Binding(nil-coalescing)

    [Swift] Optional Binding(nil-coalescing)

    Nil-Coalescing Operator → Optional Type 표현식에 값이 저장되어 있는 지 확인하고 꺼낼 필요가 없어진다. a ?? b 일 때, a는 옵셔널 값이고, 옵셔널에서 값을 추출하여 값이 있으면 a 옵셔널의 값을 반환하고, 값이 없으면 b 값을 반환한다. 예를 통해서 알아보자. 아래와 같이 옵셔널 스트링을 선언해보자. let name: String? = "Miro" 옵셔널 바인딩을 통해서 print를 해보자. if let name = name { print("Hello, \(name)") } else { print("hello, what's your name") } // Hello, Miro 만약, nil-coalescing을 사용한다면? 아래와 같이 사용이 가능하다. print("..

    [Swift] 고차함수(Map,Filter,Reduce), allSatisfy, forEach,enumerated()

    [Swift] 고차함수(Map,Filter,Reduce), allSatisfy, forEach,enumerated()

    Map 함수 컨테이너 내부의 기존 데이터를 변형하여 새로운 컨테이너를 생성한다. 예를 통해서 map 함수를 익혀보자. 아래와 같이 numbers array와 빈 doubledNumbers array를 만들어보자 let numbers: [Int] = [0, 1, 2, 3, 4] doubledNumbers = [Int]() 그리고, map함수를 통하여 numbers의 각 요소를 2배하여 새로운 배열을 반환해보자. doubledNumbers = numbers.map({ (num: Int) -> Int in return num * 2 } 위의 코드는 생략을 통하여 아래와 같이 표현할 수 있다. doubledNumbers = numbers.map { $0 * 2 } Filter 함수 filter 함수는 컨테이너 ..

    [iOS] TableView에서 Swipe해서 Delete하기

    [iOS] TableView에서 Swipe해서 Delete하기

    UITableViewDelegate 를 통하여서 구현한다! deleteRows(at:with:) Deletes the rows that an array of index paths identifies, with an option to animate the deletion. 특정 indexPath에 cell을 tableview에서 제거해준다. func deleteRows( at indexPaths: [IndexPath], with animation: UITableView.RowAnimation ) tableView(_:editingStyleForRowAt:) Asks the delegate for the editing style of a row at a particular location in a table..

    [iOS] sizeToFit()과 ToolBar

    [iOS] sizeToFit()과 ToolBar

    sizeToFit() Resizes and moves the receiver view so it just encloses its subviews. Call this method when you want to resize the current view so that it uses the most appropriate amount of space. Specific UIKit views resize themselves according to their own internal needs. 안에 있는 element(label의 경우, 글자의 intrinsic size)에 따라서 view의 사이즈가 알아서 조절되는 것! 😎 예시를 통해서 알아보자. 아래는 textfield의 extension을 통하여 keyboar..

    [iOS] Target-Action Pattern

    [iOS] Target-Action Pattern

    Target-Action Pattern 이벤트가 발생할 때 다른 객체에 메시지를 보내는 데 필요한 정보를 포함 액션 특정 이벤트가 발생했을 때 호출할 메서드를 의미 타겟 액션이 호출될 객체를 의미, 프레임워크 객체를 포함한 모든 객체가 될 수 있으나, 보통 컨트롤러가 담당한다! 만약 타켓이 nil이라면? Responde chain을 따라서 이벤트(action)을 처리하기에 적합한 리스폰더 객체를 찾아나선다! If you specify nil, UIKit searches the responder chain for an object that responds to the specified action message and delivers the message to that object. about. UIRes..

    [iOS] UIResponder

    [iOS] UIResponder

    UIResponder(feat.becomeFirstResponder) Textfield를 사용할 때 많이 쓰는 메소드인 becomeFirstResponder에대해서 공부를 하다가 UIResponder 에대해 더 깊게 공부해보자는 생각이 들었다. UIResponder란? UIResponder객체는 UIkit 앱 이벤트 처리 백본을 구성한다. 앱 이벤트 → ex) 화면 터치 UIApplication객체, UIViewController객체 및 모든 UIView객체(UIWindow포함) 모두 다 리스폰더 객체이다. 리스폰터는 UIKit이 제공하는 이벤트 정보를 사용하여서 터치 이벤트의 변경 사항을 추적하고, 앱의 인터페이스를 적절하게 업데이트한다. Responder Chain 리스폰더 객체들이 동적으로 구성된 ..

    [iOS] CGPoint, CGSize, CGRect

    [iOS] CGPoint, CGSize, CGRect

    CGPoint, CGSize, CGRect 기본적으로 view를 짜기위해서는 x,y 좌표가 필요하고, width, height가 필요하다. CGPoint View의 위치를 나타낼 때 사용한다 public struct CGPoint { public init() public init(x: Double, y: Double) public var x: Double public var y: Double } 활용 let point: CGPoint = .init(x: 10, y: 20) CGSize (width, height) 사이즈를 설정할 때 사용한다 public struct CGSize { public init() public init(width: Double, height: Double) public var w..

    [iOS] TextField 왼쪽 여백 넣기

    [iOS] TextField 왼쪽 여백 넣기

    TextField 왼쪽 여백 textField의 leftView에 UIView를 넣어주면된다!(width를 추가하여서!) 아래의 예와 같이 padding을 넣어줄 수 있다. textField.leftView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 20.0, height: 0.0)) textField.leftView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 20.0, height: 0.0)) 그리고 leftView 는 4 가지의 leftViewMode가 존재한다. .always 항상 leftview 보여주기 .whileEditing 타이핑 중일 때 leftView를 보여주기 .unlessEditing 타이핑 중이 아닐 때 ..

    [Swift] guard VS if

    [Swift] guard VS if

    guard guard문 속 else문에서는 return(or break, continue, throw)으로 즉시 종료시킨다. gurad 조건 else{ //조건이 false면 실행된다. return } guard문을 사용하는 이유? → 가독성이 훨씬 좋아진다. if문일 경우 func solution() { if condition1 { if condition2 { if condition 3 { print("come in") } else { print("bye") } } else { print("bye") } } else { print("bye") } } // 세 조건이 모두 참이면 come in, 하나라도 거짓이면 bye를 출력하는 함수이다. guard문일 경우 func solution() { guard ..

    [Swift] , 와 &&의 차이점

    [Swift] , 와 &&의 차이점

    ',' VS '&&' 먼저 논리 연산자에대해서 간단하게 복습을 하고 가보자! Operator 정리 쉽게 말하자면 && => 둘 다 참일 때만 참을 던진다 || => 둘 중 하나만 참이여도 참을 던진다. 그러면 본격적으로 '컴마'와 '&&'의 차이점에 대해서 알아보자 둘이 비슷하게 사용이 가능하지만, 옵셔널 바인딩일 때에 둘의 사용을 조심해야된다.(기본적으로 둘 다 조건이 다 참일 때 참을 던진다.) 옵셔널 바인딩 + 추가적인 condition을 동시에 쓸 경우 → 무조건 comma로 이어줘야된다. Boolean expression 두개를 연달아 이어줄 경우 → Comma와 && 둘 다 사용해도 된다. &&의 경우 두개의 boolean expression을 하나의 boolean expression으로 연산..

    [Swift] - Access Control

    [Swift] - Access Control

    Access Control(접근제어)는 다른 소스 파일 및 모듈의 코드에서, 코드의 일부에 대한 접근을 제한합니다. 모듈 → 시스템(혹은 프로그램)이나 제품 등에서 개별적인 기능이나 역할을 가진 부품, 요소/ import 시킬 수 있는 요소(Framework라고도 할 수 있다 ex. UIkit) 소스 파일 → 모듈 내의 단일 swift 소스 파일(ex. viewcontroller.swift) Access levels 아래로 갈수록 접근하기가 어려워진다! open & public internal file-private private Open VS Public 예를 통해서 한번 Open 과 Public의 차이점을 알아보자. 서브 클래싱 관점. 먼저 내가 외부의 framework MiroFramework를 만..

    [Swift] 연산 프로퍼티

    [Swift] 연산 프로퍼티

    연산 프로퍼티(Computed Property) → 값을 ‘저장’한다기보다는 특정한 연산을 통해서 값을 리턴해준다! How? getter setter 예) getter와 setter를 사용하기위해서는 저장소(tempX)가 필요하다! class Point { var tempX : Int = 1 var x: Int { get { return tempX } set(newValue) { tempX = newValue * 2 } } } var p: Point = Point() p.x = 12 위 코드에서의 setter에서 newValue는 set(newValue) { tempX = newValue * 2 } 1) 아래와 같이 써도 되고 set(miro) { tempX = miro * 2 } 2) 아예 없애도 된다..

    [Swift] 타입 프로퍼티, 타입 메소드

    [Swift] 타입 프로퍼티, 타입 메소드

    타입 프로퍼티(Type Property) - 타입 자체에 연결할 수 있으며, 처음 엑세스 할때는 게으르게 초기화(lazy initialized)가 됩니다. - 항상 초기화가 되어있어야한다. - 언제 한번 누군가 한번 불러서 메모리에 올라가면(그전까지는 올라가지 않는다= lazy), 그 뒤로는 생성되지 않으며 언제 어디서든 이 타입 - 프로퍼티에 접근 할 수 있다. ⇒ 전역변수 - static, class이라는 키워드를 통하여 구현을 한다. - 두 가지의 타입 프로퍼티가 존재합니다. 저장 타입 프로퍼티 → var , let으로 선언 가능, 기본값을 주어야된다. 연산 타입 프로퍼티 → var로만 선언이 가능 static 키워드 예를 통해서 알아보자. 아래와 같이 static을 붙혀, 저장 타입 프러퍼티와 연..

    [Swift] first 문

    [Swift] first 문

    💥 배열 속 주어진 조건을 만족하는 요소 찾기 first문 배열 속 하나하나를 클로져 안에 parameter로 넣어주어 클로져 안에 있는 body에서 첫번째로 true를 던질 때 그 요소를 가져온다. return을 생략하는 방법 return을 생략하지 않는 방법 즉, closure 안에서 return true가 나올 때까지 계속 반복하고, 안나오면 nil을 내뱉는다. closure 안에서 false가 나오면 거기서 멈추고 다음 요소로 넘어간다! 대체로 아래와 같이 return을 생략하는 방식으로 많이 사용한다. let numbers = [3, 7, 4, -2, 9, -6, 10, 1] let 넘버 = numbers.first { num in num < 0 } print(넘버) // Optional(-2)..

    [Swift] 배열 안전하게 조회하기

    [Swift] 배열 안전하게 조회하기

    💥 배열 안전하게 조회하기 🌟 배열을 안전하게 조회해야되는 이유? Array: Out of range 런타임 error가 발생이되면 프로그램이 바로 죽기 때문에 안전하게 조회를 해야된다. 따라서, 우리는 만약 out of range이면 nil을 내뱉는 서브 스크르비트 메소드를 만들어주면 된다. extension Array { public subscript (safe index: Int) -> Element? { return indices ~= index ? self[index] : nil // iOS 9 or later } } let list = [1, 2, 3] list[safe: 4] // nil list[safe: 2] // 3 🤔 ‘~=’ 연산자는 뭘까?.. 대상이 특정 범위에 속하는 지 범위를 ..

    [Swift] Optional

    [Swift] Optional

    💥 옵서널(Optional) @frozen enum Optional nil을 사용할 수 있는 타입과 그렇지 못한 타입을 구분하기 위한 수단이다. nil을 사용할 수 있는 타입을 Optional Type이라고 한다. Optional Type은 타입 옆에 ?를 붙힌다. enum 타입이며, case로는 Optional.some(Wrapped) 과 Optional.none 가 있다. → 즉, 에러가 났지만 바로 앱을 중단시키는 것이 아닌, nil을 내 뱉을거다.(기회를 한번 더 주는 것!) 어떠한 상황에서 필요한 지 예를 통해서 알아보자. 아래와 같은 경우는 우리가 예상하는대로이다. let people = ["kim": 1, "lim": 2, "hyun": 3] let name = people["kim"] //..

    [iOS] File System

    [iOS] File System

    File System 내가 어떻게 저장하고, 불러올 지 정하는 것 APFS는 mac OS, iOS, watchOS 및 tvOS의 기본 파일 시스템입니다 iOS 앱은 보안상의 이유로 파일 시스템의 sandbox directory에서 각각 관리됩니다. Sandbox directory 번들 컨테이너 실행가능한 파일, info.plist, 각종 Resources(이미지, 사운드, strings등)등을 할때 그룹화 데이터 컨테이너 Document(사용자가 직접 접근) Library(사용자가 직접 접근하지 못함) Temp iCloud 컨테이너 1) 데이터 컨테이너 - Document 설정에 따라 유저가 직접 파일 추가 및 삭제 가능> 따라서 유저에 의해 삭제되거나 내용이 변경되어도 무방하고 유저가 다루는 컨텐츠와 ..

    [iOS] MVC

    [iOS] MVC

    SW architecture 와 SW design pattern의 개념 차이 , 왜 필요할까? SW architecture란? 수많은 기능 하나하나의 부품들을 어떻게 연결시켜 관계를 맺었는지를 결정하는 것 이러한 모듈들을 어떻게 분할하고 배치할 것인가? 및 구성관계 설정 작은 기능 → 모듈 모듈을 기능별로 묶어놓은 집합 → 컴포넌트 전체 → 라이브러리 SW architecture의 기본원리 모듈화 ⇒ 소프트웨어 성능 향상 및 유지관리 등이 용이하도록 시스템의 기능을 모듈단위로 나누는 것 추상화 ⇒ 전체적이고 포괄적인 개념을 설계한 후에 구체화시켜 나가는 것 단계적 분해 ⇒ 상위 개념부터 하위 개념으로 구체화 시키는 분할 기법 하향식 설계 전략 정보은닉 ⇒ 모듈 내부에 정보와 자료들을 숨겨서 다른 모듈이 ..

    [iOS] Singleton(싱글톤)

    [iOS] Singleton(싱글톤)

    싱글톤이란? Design Pattern 중 하나이다. 타입 프로퍼티로 선언이 되어있으므로, lazy 하게 initialize가 된다. 특정 용도로 객체를 하나만 생성하여, 공용으로 사용하고 싶을 때 사용하는 디자인 유형 하나의 instance에 어느 클래스에서든 접근 가능하게 하는 것! “이 클래스에 대한 Instance는 최초 생성될 때 딱 한번만 생성해서 전역에 두고, 그 이후로는 이 Instance만 접근 가능하게 하자”할 때 사용이된다. 싱글톤을 언제 사용하면 좋을까? class UserInfo { var id: String? var password: String? var name: String? } 위의 코드와 같이 UserInfo를 담는 class를 만든다고 생각해보자. 근데 각 3개의 vie..