목록전체 글 (65)
develop
AutoLayout FirstItem AutoLayout가 적용된 첫번째 컨텐츠이다. SecondItem AutoLayout가 적용된 두번째 컨텐츠이다. 고정값으로 준 Width나 Height같이 컨텐츠의 연결이 필요없는 오토레이아웃은 SecondItem이 필요없다. Relation Greater Than or Equal (같거나 클수 있다), Less Than or Equal (같거나 작을수 있다), Equal(같다) 를 적용할수 있다. 예를들어 superView에 view를 넣고 상하좌우에 constant를 0만 주었을때는 view가 superView의 크기를 따라가는데Relation을 주면 view의 컨텐츠의 길이가 superView의 크기보다 크지 않을때까지 view의 컨텐츠 크기를 따라가다가 s..
blocking vs non-blocking blocking class Network { var isLoading = false func blocking() -> Bool { print("start date: \(Date().timeIntervalSince1970)") sleep(1) print("end date: \(Date().timeIntervalSince1970)") return true } } class Example { init() { let network = Network() let result = network.blocking() print("complete \(result) date: \(Date().timeIntervalSince1970)") } } start date: 15442499..
세마포어를 사용하기 전에 세마포어가 왜 생겼는지 알아보자 하나의 자원에 접근할 때 동시에 여러 쓰레드에서 그 하나의 자원에 접근한다면? var array = [Int]() DispatchQueue.global().async { for element in 0...1000 { array.append(element) } } DispatchQueue.global().async { for element in 0...1000 { array.append(element) } } malloc: *** error for object 0x10b4d6cb0: pointer being freed was not allocated malloc: *** set a breakpoint in malloc_error_break to de..
연관 타입이라고 한다. protocol ExampleProtocol { var value: Int { get } } 위와 같은 프로토콜이 있다고 가정해 보자 코드에서 이 프로토콜을 공통적으로 사용을 하는데 value가 String이 필요한 화면이 있다. 그래서 하나 더 만들면 protocol ExampleProtocol2 { var value: String { get } } 그러다가 value가 Int와 String 둘다 받을 수 있게 되었다. 그러면 value를 어디서든 사용할수 있게 타입을 AnyObject로 해보자 protocol ExampleProtocol { var value: AnyObject { get } } class Example: ExampleProtocol { var value: An..
convenience는 편의 생성자라고 한다. 기존에 구현 했던 init을 수정하지 않고 custom한 init을 사용할 수 있다. 사용 방법은 init앞에 convenience을 붙인다. 그리고 convenience로 구현한 init은 동일한 클래스에서 다른 init을 호출하여야 한다. 그렇지 않으면 아래와 같은 에러가 나타나게 된다. 'self.init' isn't called on all paths before returning from initializer class SuperClass { let name: String let age: Int init(name: String, age: Int) { self.name = name self.age = age } init(name: String) { s..
App LifeCycle 앱은 항상 5가지 상태중의 하나에 있다. Not Running: 앱이 실행되지 않은 상태 Inactive: 앱이 실행중인상태지만 이벤트없음 Active: 앱이 실행중이며 이벤트가 발생 Background: 앱이 백그라운드에 있지만 실행되는 코드가 있음 Suspened: 앱이 백그라운드에 있고 실행되는 코드가 없음 5가지의 상태 들의 이벤트를 관리하는 곳이 UIApplicationDelegate 프로토콜이다. Launch: 앱이 실행되지 않은 상태에서 비활성 또는 백그라운드 상태로 전환된다. func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication...
ARC(Automatic Reference Counting) 클래스의 인스턴스를 만들고 참조할 때 ARC가 인스턴스에 대한 정보를 메모리에 할당한다. 프로퍼티, 상수, 변수에 레퍼런스가 지정되면 카운트가 올라가고 해제되면 내려가고 0이되면 해제한다. 자동 레퍼런트 카운터는 더 이상 사용되지 않는 시점을 결정하여 메모리를 해제한다. 메모리가 제대로 해지되지 않는 경우가 있다. 순환참조 두 클래스 인스턴스의 프로퍼티가 서로를 강한 참조할 경우 class Example1 { deinit { print("deinit Example1") } var example2: Example2! } class Example2 { deinit { print("deinit Example2") } var examle1: Examp..
함수에서 클로져를 쓸 때 보통 아래와 같이 쓴다. func example(_ handler: (() -> Void)) { } func example(_ handler: ((Int) -> Int)) { } 이렇게 함수에 클로져를 쓰다보면 아래와 같은 에러가 나올때가 있다. 물론 에러를 누르고 fix를 하면 자동으로 클로져에 @escaping 가 붙는다. escaping는 탈출한다는 뜻이고 클로져가 함수를 탈출할 때 붙는다. noescape는 함수를 탈출하지 않을때 사용되며 생략한다. 즉, 그냥 클로져를 사용하면 noescape로 된다. 클로져가 함수를 탈출하는 상황은 두가지가 있다. 비동기 실행: 클로저가 비동기로 실행되면 클로저를 잡고 있어야한다. 저장소: 클로저를 변수나 프로퍼티에 저장할 때. 비동기 ..
enum 기본으로 아래와 같이 사용할 수 있다. enum CompassPoint { case north case south case east case west } 아래와 같이 case를 생략 할 수 있다. enum CompassPoint { case north, south, east, west } 아래와 같이 enum의 값을 가져올 수 있다. let value = CompassPoint.north RawValue enum CompassPoint: Int { case north, south, east, west } print(CompassPoint.north.rawValue) print(CompassPoint.south.rawValue) 0 1 제일 앞의 값은 0부터 시작한다. RawValue에 초기값을 ..
이전글 2021/01/01 - [iOS] - Subscript 에서 설명한 Subscript에 값을 Optional로 사용합니다. Dictionary에 Subscript를 사용하면 Optional로 나온다. let dict = ["a": 1, "b": 2] let a = dict["a"] print(a) Optional(1) 하지만 Array에 Subscript를 사용하면 데이터 그대로 나오게 된다. let array = [1, 2, 3, 4, 5, 6, 7] let first = array[0] print(first) 1 UITableView 나 UICollectionView 를 사용할때 Array로 데이터를 가져올때 Array가 변하게 되면 Fatal error: Index out of range 에..
subscript(index: Int) -> Int { get { } set { } } 또는 subscript(index: Int) -> Int { // get만 있는 subscript } 이렇게 사용할 수 있다. Dictionary 타입에서는 key-value subscript로 구현되며 해당 key값의 옵셔널 타입을 받거나 리턴한다. Array 타입에서는 index를 받고 해당 index의 값을 받거나 리턴한다. 예제를 보면 struct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let timesTable = TimesTable(multiplier: 3) print(timesT..
스위즐링은 런타임에 해당 메서드를 내가 원하는 메서드로 바꿀 수 있다. extension UIViewController { @objc private func customViewWillAppear(_ animated: Bool) { print("customViewWillAppear 호출") } public static func swizzleMethodInitialize() { let originalSelector = #selector(viewWillAppear(_:)) let swizzledSelector = #selector(customViewWillAppear(_:)) let originalMethod = class_getInstanceMethod(UIViewController.self, origina..
1. CustomView IBDesignable 만들기 @IBDesignable class CustomView: UIView { } 2. CustomView에 IBInspectable 추가하기 @IBDesignable class CustomView: UIView { @IBInspectable var labelText: String? { set { self.label.text = newValue } get { return self.label.text } } @IBInspectable var labelTextColor: UIColor? { set { self.label.textColor = newValue } get { return self.label.textColor } } @IBInspectable va..
위와 같이 Face로 추정되는 곳에 Blur처리 또는 이미지로 합칠 수 있다. CIDetector를 사용하여 face를 찾기 private func faceDetector(_ image: UIImage?) { guard let image = image, let ciImage = CIImage(image: image), let ciDetector = CIDetector( ofType: CIDetectorTypeFace, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh] ) else { return } let features = ciDetector.features(in: ciImage) if features.isEmpty { retur..
func makeLabel() -> UILabel? { let label = UILabel() label.frame = CGRect(x: 150, y: 200, width: 200, height: 20) label.text = "Hello World!" let textSize = (label.text ?? "").size(withAttributes: [NSAttributedString.Key.font : label.font]) let tempLabel = UILabel(frame: CGRect(x: 0, y: 0, width: textSize.width, height: .greatestFiniteMagnitude)) tempLabel.numberOfLines = 0 tempLabel.text = labe..