1. 개요 들여쓰기 칸 수, 공백 등.. 코드를 작성하는 스타일은 사람마다 다를 수 있다. 그런데 협업을 하는 경우에도 한 프로젝트 내에 사람들의 각기 다른 습관들이 나타난다면 코드를 읽기가 참 힘들어질 것이다. 그래서 이런 약속들을 swiftLint, swiftFormat을 사용하여 정해둔다. 물론, 협업을 하지 않는 경우에도 코드 내에 사용되지 않는 등 불필요한 코드들을 관리할 수 있다. 2. SwiftLint swiftLint는 정한 규칙을 어길 시, warning이나 error를 표시해주는 역할을 한다. 제공되는 규칙과 사용방법은 다음 링크에서 확인할 수 있다. Rule Directory Reference realm.github.io 참고로 필자는 프로젝트에서 다음과 같은 규칙을 정하였다. # 한..
1. 정규표현식 func isOutOfRangePassword(passwordText: String) -> Bool { let rangeRegex = /^password:.{8,16}$/ if passwordText.prefixMatch(of: rangeRegex) == nil { return true } return false } 정규표현식을 사용하여 받은 문자열의 패턴을 파악하는 것은 흔히 사용되는 방법이다. 그런데 패턴 뿐만 아닌, 원하는 패턴의 문자열을 정규표현식을 사용하여 추출하는 것도 가능하다. 바로 예제를 보자. 2. name capture func isOutOfRangePassword(passwordText: String) -> Bool { let rangeRegex = /^password..
1. closure에서 self를 쓰면 무조건 순환참조? closure로 값을 넘겨주고, 그 안에서 self를 호출할 일이 있을 때 순환 참조를 우려하여 weak self를 종종 사용하였다. 그런데, 모든 closure라고 항상 self를 쓴다고 순환 참조가 발생하지 않는다. 2. non-escaping closure의 경우 위 그림과 같이 함수가 return 되며 closure도 함께 메모리에서 사라지기 때문에 순환참조를 우려할 필요가 없다. class A와, 그 안에서 함수와 함수에서 사용되는 closure 가 있다고 가정하자. 여기서 closure 안에 self를 사용하여도, self 안이 아닌 func 안에 closure이 존재하기에, func가 사라지면 closure도 사라지기에 순환참조가 발생..
1. dequeueReusableCell collectionView.dequeueReusableCell(withReuseIdentifier: ****, for: ****) 우리가 아는 것처럼 cell을 재사용하는데 사용한다. 참고) [iOS] CollectionView Xib 파일 생성하여 Custom Cell로 구현하기 1. Collection view 생성 2. Custom Cell에 대한 class 생성 3. Xib 파일 생성 4. File's Owner, Custom Class 란에 방금 생성한 custom cell의 class 입력 5. 재사용 식별자 등록(여기선 "cell" 로 등록, 원하는 아무 문자로 설 pushedgun.tistory.com cell에 값을 넣어주기만 하는 기능에서는 문제..
1. 더러운 switch 문 코드를 짜다, 다음과 같은 흉측한 switch 문이 만들어졌다. func idState(id: String) -> IDState { if isOutOfRangeID(id: id) { idState = false return .outOfRange } else if isDuplicateID(id: id) { idState = false return .duplicate } idState = true return .success } 똑같은 idState 코드가 몇 번이나 반복된다. idState = false 를 if문 위로 올려주는 방법도 있겠지만, 프로젝트에서 이 프로퍼티의 특성상 종료되는 순간에 확실한 bool 값을 가지도록 하여야 하였다. 2. defer 예전 NSLock을 ..
1. 타입 캐스팅해서 쓰는 게 맞나...? protocol Shape { var color: Color { get, set } } class Square: Shape { var color: Color var text: String ..생략.. } // func get() -> Shape { //추상 타입으로 값을 리턴해주기에, shape에 있는 형태밖에 사용하지 못한다. let square = Square(..생략..) return square } //사용할 때 let a = get() a.color a.text//에러!! 위와 같이 이 추상화 protocol로 호출할 경우 해당 protocol의 인터페이스대로 사용할 수밖에 없다. 2. Some 사용하면, 구체 타입을 직접 사용할 수 있다!! 바로 예제..
원하는 타이밍에 비동기 처리를 할 수 있게 해준다. 이게 무슨 말일까?? 각설하고 바로 예제를 보자. 1. Completion Handler 예제 모든 method에 completion 인자를 추가해주면, completion Handler를 사용하는 인자로 바꿀 수 있다. func A(completion: () -> ()) { ...10초 걸리는 작업.. completion() ...10초 걸리는 작업.. } func B() -> () { ...5초 걸리는 작업.. } //Completion Handler A(completion: B) // -> A가 호출되고 10초 뒤, B가 비동기로 실행된다. 그림으로 표현하자면 다음과 같다. A 함수 내부에 completion()을 적어둔 시점에서 B가 호출되며, ..
아래와 같이 closure을 인자로 보낼 때, 직접 method를 넣어 보내지 않고 { }을 통해 보낼 수 있다. //아래와 같은 함수의 경우 func A(task:() -> ()) { ... } func B() { ... } //기본 A(task: B) //Trailing Closure //이렇게도 사용할 수 있다! A() { () -> () in B() }