ToDo
✅ Udemy 컴공선배 강의
✅ 운동

✅ Swift DelegatePattern

 

이번주만 탈락의 고배를 여러번 느꼈는데요,,하하 그러던중 오늘 한 영상을 보았습니다.

침착맨의 "대충 동기 부여하는 영상" 인데요, 조금 울적하던중 위로를 받았습니다 ^_^

궤도님이 한 말이 가장 마음에 남습니다.

"50%확률일때 하지않으면 다음 성공확률도 50%이다. 무조건 시도를 해봐야 다음 성공 확률이 올라간다는 의미입니다."

 

계속 도전하면서 다음 성공 확률을 조금씩 늘려가겠습니다 ^_^

 

나를 위로해준 최고 침착맨 고마워🙏

배운점

오늘은 간단히 회원가입을 할때 유효성 검사를 하기 위한 정규표현식을 같이 알아보았습니다.

    func isValidPassword() -> Bool {
        //비밀번호는 대,소문자,특수문자,숫자 and 8자이상
        let regularExpression = "^(?=.*[A-Z])(?=.*[a-z])(?=.*[\\d])(?=.*[~!@#\\$%\\^&\\*])[\\w~!@#\\$%\\^&\\*]{8,}$"
        let passwordValidation = NSPredicate.init(format: "SELF MATCHES %@", regularExpression)
        
        return passwordValidation.evaluate(with: self)
    }
    
    
    func isValidEmail() -> Bool {
        // @ 2글자
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        let emailTest = NSPredicate.init(format: "SELF MATCHES %@", emailRegEx)
        
        return emailTest.evaluate(with: self)
    }

 

 

자주 쓰는 정규식

대문자만

"^[A-Z]*$"

 

소문자만

"^[a-z]*$"

 

숫자만

"^[0-9]*$"
"^[\\d]*$"

// 반대 (숫자 제외)
"^[\\D]*$"

 

알파벳 + 숫자

"^[0-9a-zA-Z]*$"
"^[\\w]*$"

// 반대 (알파벳, 숫자 제외)
"^[\\W]*$"

 

숫자, 알파벳, 특수문자 (~!@#$%^&*)

"^[0-9a-zA-Z~!@#\\$%\\^&\\*]*$"
"^[\\w~!@#\\$%\\^&\\*]*$"

 

최소 하나 이상 something

"(?=.*[something])"

 

최소 하나 이상의 대문자, 하나 이상의 소문자, 하나 이상의 숫자

"(?=.*[A-Z])(?=.*[a-z])(?=.*[\\d])"

 

최소 하나 이상의 대문자, 하나 이상의 소문자, 하나 이상의 숫자, 하나 이상의 특수문자(~!@#$%^&*), 그 외 불포함

"^(?=.*[A-Z])(?=.*[a-z])(?=.*[\\d])(?=.*[~!@#\\$%\\^&\\*])[\\w~!@#\\$%\\^&\\*]{8,}$"

 

생각과 감정

위로해준 침착맨에게 감사해🙏

 

앞으로의 계획선언

인스타그램 클론한후 기능 붙이기에 돌입해보겠습니다 ^_^ 빻쉬

 

'TIL' 카테고리의 다른 글

TIL_20231126  (0) 2023.11.26
TIL_20231120  (0) 2023.11.20
TIL_20231113  (0) 2023.11.13
TIL_20231107  (0) 2023.11.07
TIL_20231006  (0) 2023.10.06

안녕하십니까..ㅎㅎ 당차게 애플아카데미를 2번 지원했었지만 인터뷰를 해보지도 못하고 떨어졌군요~~
어제는 조금 매음이 아프고 세상이 미웠지만 다시일어났습니다 하하~~

뭐 어쩌겠습니까 다른걸 또 도전하면 되지않겠나요!! 그래서 11월달에 메쉬업에 지원을 하려 합니다~!

그전에 저의 내실을 많이 쌓아 둬야겠죠? 다른 분들에게 많은 도움이 되어야죠 ㅎㅎ (실상 도움을 많이 받는편)
어제 다하지 못한 후행클로저를 공부한후 "객체지향의 사실과 오해"를 조금 읽어보려 합니다~ 화이팅!!

 

배운점

후행클로저에 대해 알아보았습니다.

 

후행클로저

함수의 마지막 인수로 함수에 클로저 표현식을 전달해야하고 클로저 표현식이 긴 경우 후행 클로저를 사용한다고 합니다!

예제를 보면서 알아보았습니다.

func someFunctionThatTakesAClosure(closure: () -> Void) {
    // function body goes here
}

// Here's how you call this function without using a trailing closure:

someFunctionThatTakesAClosure(closure: {
    // closure's body goes here
})

// Here's how you call this function with a trailing closure instead:

someFunctionThatTakesAClosure() {
    // trailing closure's body goes here
}

위의 코드에서 someFunctionThatTakesAClosure 함수는 하나의 매개변수를 가지고 있습니다.

이 매개변수는 closure라는 이름의 클로저입니다.

someFunctionThatTakesAClosure함수를 호출할 때 closure 매개변수에 클로저를 전달합니다. 클로저는 중괄호로 묶여 있습니다.

 

someFunctionThatTakesAClosure함수를 호출할 때 후행 클로저를 사용합니다! 

후행클로저는 함수의 마지막 매개변수로 전달되기 때문에 매개변수 이름을 생략할 수 있습니다.

 

마지막 someFunctionThatTakesAClosure()의 부분을 보시면 코드를 더욱 간결하게 사용할 수 있습니다.

특히 함수의 마지막 매개변수가 클로저인 경우 후행클로저를 사용하면 코드가 더욱 깔끔해집니다!!

주의할 점은 후행 클로저는 함수의 마지막 매개변수로만 사용할 수 있다는 점입니다!

 

reversedNames = names.sorted() { $0 > $1 }

문자열 정렬 클로저는 메서드의 소괄호 밖에 작성될 수 있습니다!

 

reversedNames = names.sorted { $0 > $1 }

후행 클로저로 표현식이 함수와 메서드의 유일한 인수일 경우 함수를 호출할때 ()를 생략해도 좋습니다!

 

후행 클로저는 클로저가 길어서 한줄로 인라인으로 작성이 불가능 할 때 유용합니다.

let digitNames = [
    0: "Zero", 1: "One", 2: "Two",   3: "Three", 4: "Four",
    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]

위의 예제는 0은 "Zero"등으로 숫자를 그에 해당하는 영어로 매핑하는 딕셔너리 입니다!

numbers 배열을 사용하여 후행 클로저로 map(_:)메서드로 클로저 표현식을 작성하여 String값의 배열을 생성 할 수 있습니다.

let strings = numbers.map { (number) -> String in
    var number = number
    var output = ""
    repeat {
        output = digitNames[number % 10]! + output
        number /= 10
    } while number > 0
    return output
}
// strings is inferred to be of type [String]
// its value is ["OneSix", "FiveEight", "FiveOneZero"]

클로저 몸체를 보시면,

number를 number로 초기화 하고있습니다.

output 변수를 ""로 초기화 하고있습니다.

repeat으로 number가 0이 될때까지 반복합니다.

반복문의 각 반복에서 클로저는 number의 나머지를 구하고, 해당하는 영어 이름을 output변수에 추가합니다. 

마지막으로 클로저는 output 변수의 값을 반환합니다.

따라서 map함수는 numbers 배열의 각 요소에 대해 위의 클로저를 실행하고, 각 요소에 대한 클로저의 결과를 배열 strings에 저장합니다.

( 딕셔너리의 서브 스크립트는 키가 존제하지 않는 경우에 값을 찾는걸을 실패하기 위해 옵셔널 값을 반환합니다! 따라서 digitNames뒤에 !를 붙여줍니다.)

 

 

함수가 여러개의 클로저를 가지고 있다면 첫번째 후행 클로저의 인수 라벨을 생략하고 남은 후행 클로저의 라벨을 표기합니다.

func loadPicture(from server: Server, completion: (Picture) -> Void, onFailure: () -> Void) {
    if let picture = download("photo.jpg", from: server) {
        completion(picture)
    } else {
        onFailure()
    }
}

completion과 onFailure의 두개의 클로저를 가지고 있는 모습입니다.

completion은 사진을 다운로드 한후 보여주는 완료처리이고,

onFailure는 오류를 표시하는 오류 처리기 입니다.

 

 

캡처값

클로저는 정의된 둘러싸인 컨텍스트에서 상수와 변수를 캡처(capture)할 수 있습니다? (캡처를 알아봐야 겠습니다,)

 

"개발자 소들의"님의 블로그에서 발췌한 내용입니다.

func doSomething() {
    var num: Int = 0
    print("num check #1 = \(num)")
    
    let closure = {
        print("num check #3 = \(num)")
    }
    
    num = 20
    print("num check #2 = \(num)")
    closure()
}

(클로저는 Value/Reference 타입에 관계없이 캡쳐하는 값들을 참조함!! 이것을Reference Capture라고 함)



클로저는 num을 캡처합니다! 즉 num이란 변수를 참조 한다고 합니다.

클로저를 실행하기 전에 num이란 값을 외부에서 변경하면 클로저 내부에서 사용하는 num의 값또한 변경됨!!

 

(다시 document로...)

Swift에서 값을 캡처할 수 있는 간단한 클로저 형태는 다른 분문 내에 작성하는 중첩함수 입니다. 

중첩함수는 바깥 함수의 어떠한 인수도 캡처할 수 있고, 바깥 함수 내에 정의된 상수와 변수를 캡처 할 수 있습니다.

(이해가 조금 어려우니 예제를 보면서 이해하겠습니다!)

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

incrementer는 중첩함수로 makeIncrementer함수의 내부에 정의되어 있습니다.

incrementer()함수는 둘러싸인 컨텍스트에 runningTotal과 amount값을 캡처합니다. 이값을 캡처한 후 incrementer는 호출할때마다

amount로 runningTotal을 증가시키는 클로저로 makeIncrementer에 의해 반환됩니다.

makeIncrementer의 반환타입은 () -> Int 입니다. 이것은 함수를 반환한다는 의미입니다!


incrementer() 함수는 파라미터가 없으며 함수 본문 내에 runningTotal 과 amount 를 참조하고 있습니다. 둘러싸인 함수에 runningTotal 과 amount 대한 참조 (reference) 를 캡처하고 함수 내에서 사용합니다. 참조를 캡처하는 것은 makeIncrementer 호출이 종료될 때 runningTotal 과 amount 가 사라지지 않고 다음에 incrementer 함수가 호출될 때 runningTotal 을 사용할 수 있습니다.

 

func incrementer() -> Int {
    runningTotal += amount
    return runningTotal
}

단독으로 보면 incrementer 함수는 비정상적으로 보일 수 있습니다.

incrementer 함수는 파라미터가 없으며 함수 본문 내의 runningTotal과 amount를 참조하고 있습니다.

runningTotal과 amount에 대한 참조(reference)를 캡처하고 함수 내에서 사용합니다!
참조를 캡처하는 것은 makeIncrementer호출이 종료될 때 runningTotal과 amount가 사라지지 않고 다음에 incrementer함수가 호출될때 runningTotal을 사용할 수 있습니다!!

 

 

클로저는 참조 타입

참조하는 클로저는 캡처한 runningTotal을 계속 증가시킬수 있는 이유는 함수와 클로저가 참조타입(reference tpyes)이기 때문입니다!

 

뒷부분은 ARC를 공부한후 다시오도록!
- 엡! 삐~

 

 

생각과 감정

이전엔 졸업까지 별로 남지 않아 마음이 많이 조급했던것 같습니다! 흠... 다른분들에게 조언을 받고 여러 유튜브 영상을 보아도 천천히 자기페이스에 맞춰서 공부하는게 모쪼록 도움이 크다고 했지요.. 하하 저도 천천히 저의 페이스에 따라 나아가려 합니다!!

iOS개발자가 되는 그날까지 크흡... 화이또..!  

 

앞으로의 계획선언

ARC와 캡처, 탈출클로저에 대해 더욱 자세하게 알아봐야 겠습니다!!

 

 

 

 

https://babbab2.tistory.com/83

 

Swift) 클로저(Closure) 정복하기(3/3) - 클로저와 ARC

안녕하세요 :) 소들입니다! 이번 포스팅은 클로저 정복하기 마지막 편!!! 메모리나 ARC에 대한 사전 지식이 없으면 조금 이해하기 어려울 수 있으니, 메모리 관련 포스팅을 먼저 보고 오심을 추천

babbab2.tistory.com

 

'TIL' 카테고리의 다른 글

TIL_20230921  (0) 2023.09.21
TIL_20230918  (0) 2023.09.18
TIL_20230914  (0) 2023.09.14
TIL_20230912  (0) 2023.09.12
TIL_20230911  (0) 2023.09.11

+ Recent posts