전 포스팅(브런치 쓰고 블로그로 옮김) 이후,

갓 졸업한 대학생(지인)이 스냅 킷에서 value.snp.makeConstraints { (s) in 

하거나

value.snp.makeConstraints { (make) in

를 하거나


-> Void를 넣거나 뺄 때  왜 그게 모두 동작하는지 모르겠다고 해서


설명해 주다가 잘 알아듣기에 내용이 괜찮은 같아서 글로 옮겨본다.


import UIKit


let myFunc : (String, String) -> Void = { (x, y) in

    print("first String is ", x)

    print("second String is ", y)

}


myFunc("hello", "world")


사실 파라미터를 x, y로 받던 a, b로 받던 중요치 않다. 


그런데 이해시키려면 사실상 클로저를 처음부터 끝까지 설명해야 했다. 나의 경우 제대로 이해하지 않고 그냥 잘 아는 프로그래밍 언어에 빗대어 이해를 해버렸기에 이해하고 설명한다기보다 그냥 실무에서 쓰니까 쓰는 대로 설명을 했고, 중생의 이해를 도왔던 내용을 글로 옮기며 상황극을 해 본다.


함수의 필요성을 설명하려고 online 에서 텍스트를 텍스트 그림으로 변경해주는 것을 돌려서 붙였는데 여기에서 다 깨지네 ㅡㅡ; 본 의도만 이해해 주길 ㅠㅠ


시키면 바로 만드는 개발자 - 시바견이 씀.


> 헬로 월드를 찍으라고 했다.

# 누가 만들어 놓은 API를 호출하기만 했다.


import UIKit

print("Hello world")



> 헬로 월드를 두 번 찍으라고 했다.

# 두 번 호출했다.


print("Hello world")

print("Hello world")



> 예쁘게 만들라고 했다.

# 누가 만들어 놓은 API를 호출하기만 했다.


print(".__           .__  .__                               .__       .___")

print("|  |__   ____ |  | |  |   ____   __  _  _____________|  |    __| _/")

print("|  |  \\_/ __ \\|  | |  |  /  _ \\  \\ \\/ \\/ /  _ \\_  __ \\  |   / __ | ")

print("|   Y  \\  ___/|  |_|  |_(  <_> )  \\     (  <_> )  | \\/  |__/ /_/ | ")

print("|___|  /\\___  >____/____/\\____/    \\/\\_/ \\____/|__|  |____/\\____ | ")

print("     \\/     \\/                                                  \\/ ")



> 두 번 출력하라고 했다.

# LOC가 길어져서 함수로 만들었다.


func hw() {

    print(".__           .__  .__                               .__       .___")

    print("|  |__   ____ |  | |  |   ____   __  _  _____________|  |    __| _/")

    print("|  |  \\_/ __ \\|  | |  |  /  _ \\  \\ \\/ \\/ /  _ \\_  __ \\  |   / __ | ")

    print("|   Y  \\  ___/|  |_|  |_(  <_> )  \\     (  <_> )  | \\/  |__/ /_/ | ")

    print("|___|  /\\___  >____/____/\\____/    \\/\\_/ \\____/|__|  |____/\\____ | ")

    print("     \\/     \\/                                                  \\/ ")

}


# 메서드를 호출했다.


hw()

hw()


> 다섯 번 해달라고 했다.

# 제어문을 썼다.


for _ in 0..<5 {

    hw()

}


> 클래스가 뭔지 물었다.

# 클래스는 중요치 않아, 네가  하는지가 중요해. 다만 이제부터는 메모리를 알아야 해


class yourRequirement {


   func hw() {

        print(".__           .__  .__                               .__       .___")

        print("|  |__   ____ |  | |  |   ____   __  _  _____________|  |    __| _/")

        print("|  |  \\_/ __ \\|  | |  |  /  _ \\  \\ \\/ \\/ /  _ \\_  __ \\  |   / __ | ")

        print("|   Y  \\  ___/|  |_|  |_(  <_> )  \\     (  <_> )  | \\/  |__/ /_/ | ")

        print("|___|  /\\___  >____/____/\\____/    \\/\\_/ \\____/|__|  |____/\\____ | ")

        print("     \\/     \\/                                                  \\/ ")

    }   

}


# 이렇게 만들면,

# yourRequirement.hw() 이렇게 호출할 수 있는데 코드는 있어도 메모리에는 없어.


> 메모리가 뭐지?

# 이 세상. 메모리에 없으면 이 세상에 없는 거야. 코드는 있어도 만들어지지 않은 것.


class yourRequirement {


    static func hw() {

        print(".__           .__  .__                               .__       .___")

        print("|  |__   ____ |  | |  |   ____   __  _  _____________|  |    __| _/")

        print("|  |  \\_/ __ \\|  | |  |  /  _ \\  \\ \\/ \\/ /  _ \\_  __ \\  |   / __ | ")

        print("|   Y  \\  ___/|  |_|  |_(  <_> )  \\     (  <_> )  | \\/  |__/ /_/ | ")

        print("|___|  /\\___  >____/____/\\____/    \\/\\_/ \\____/|__|  |____/\\____ | ")

        print("     \\/     \\/                                                  \\/ ")

    }   

}


> 이 세상(메모리)에 있게 하려면?

# 스태틱으로 펑션(메서드, 함수)를 지정하면 메모리에 바로 만들어져(생성) 그래서 호출 가능해.


yourRequirement.hw()


> static 만 되는 거야?

# static 은 안 쓰겠다면


yourRequirement().hw()


# () 로 클래스 자체를 메모리에 생성해서 hw를 실행할 수 있어, 괄호()는 매우 중요한 개념이야.

# 메모리에 생성한다 는 개념과 호출(실행)을 뜻해.


>  사람 여러 명 만들려면?

# 그때는 static을 쓰면 안 돼. static은 싱글톤이라 한 번만 생성되어서 공유가 되는 것이지. 텔레파시야 괜찮을 것 같긴 한데...



let h1 = human()

let h2 = human()


# 처럼 static으로 만들지 말고 각각 만들어서 지칭하는 객체 변수(인스턴스 변수, 포인터 변수)를 지정하면 되거든.


> 클래스로 사람도 만들어?

# 설명은 위해... 많은 print 묶기 위해 함수(API)를 쓴다는 것을 알았으니, 다시 한 줄로 다시 표현해 보자.

# 그리고 클래스 이름을 바꾸어 보자.


class human {

    func hw() {

        print("Hello, world")

    }

}


# 함수 이름도 refactoring 해보자.(더 좋게 바뀌어 보자)


class human {

    func speak() {

        print("Hello, world")

    }

}


# 사람 객체가 만들어졌어.

> 얼굴도 있어?


# property 만들면 되지


import UIKit


class human {


    let face : String = "face"


    func speak() {

        print("Hello, world")

    }


}


> 눈은?

# 멤버 변수 만들면 되지


class human {


    let face : String = "face"

    let eyes : String = "eyes"


    func speak() {

        print("Hello, world")

    }

}


> 에이 그냥 글자네

# 그리면 되지


        let face = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))

        let eye = UIView(frame: CGRect(x: 10, y: 10, width: 30.0, height: 30.0))

        eye.layer.cornerRadius = 17.0

        eye.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)


        let eye2 = UIView(frame: CGRect(x: 60, y: 10, width: 30.0, height: 30.0))

        eye2.layer.cornerRadius = 17.0

        eye2.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)

        face.addSubview(eye)

        face.addSubview(eye2)

        return face


> 함수에 넣어?

# 그래도 되고


import UIKit

import PlaygroundSupport


class human {


    var face : UIView = faceMaker()


    func speak() {

        print("Hello, world")

    }


    static func faceMaker() -> UIView {

        let face = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))

        let eye = UIView(frame: CGRect(x: 10, y: 10, width: 30.0, height: 30.0))

        eye.layer.cornerRadius = 17.0

        eye.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)


        let eye2 = UIView(frame: CGRect(x: 60, y: 10, width: 30.0, height: 30.0))

        eye2.layer.cornerRadius = 17.0

        eye2.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)

        face.addSubview(eye)

        face.addSubview(eye2)

        return face

    }

}



> 다시 static을 썼네?

# 어쩔 수 없어 클래스가 생성된 이후에 function을 쓸 수 있는데 클래스가 객체가 될 때(객체가 생성될 때)

  모든 프로퍼티가 세팅이 되어야 하거든. 프로퍼티 세팅을 만들어지지 않은 함수로 할 수는 없으니 static으로 할 수밖에 없어.


> 그럼 해당 func는 한 번만 생성되는 거야?

# 응, 중복 작업의 경우엔 메모리도 작게 먹고 좋겠지만 객체 지향 프로그램 개념과는 조금... 아니지.


> 다른 방법은 없어?

# 함수를 구현하고 바로 생성해서 대입하면 되지.


import UIKit

import PlaygroundSupport


class human {

    let face : UIView = {

        let face = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))

        let eye = UIView(frame: CGRect(x: 10, y: 10, width: 30.0, height: 30.0))

        eye.layer.cornerRadius = 17.0

        eye.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)


        let eye2 = UIView(frame: CGRect(x: 60, y: 10, width: 30.0, height: 30.0))

        eye2.layer.cornerRadius = 17.0

        eye2.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)

        face.addSubview(eye)

        face.addSubview(eye2)

        return face

    }()


    func speak() {

        print("Hello, world")

    }

}


let h1 = human()


> 호출할 때 파라미터는 어떻게 넣어?

# 그냥 넣으면 되지


> 어떻게 받아?

# $0, $1, $2로



    let face : UIView = {

        let face = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))

        let eye = UIView(frame: CGRect(x: 10, y: 10, width: 30.0, height: 30.0))

        eye.layer.cornerRadius = 17.0

        eye.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)


        let eye2 = UIView(frame: CGRect(x: 60, y: 10, width: 30.0, height: 30.0))

        eye2.layer.cornerRadius = 17.0

        eye2.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)

        face.addSubview(eye)

        face.addSubview(eye2)

        print($0, $1, $2)

        return face

    }(10, 12, 13)



> 쉽네

# 원래 이게 쉬워진 거지


import UIKit

import PlaygroundSupport


class human {

    let face : UIView = { (s0, s1, s2) -> UIView in

        let face = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))

        let eye = UIView(frame: CGRect(x: 10, y: 10, width: 30.0, height: 30.0))

        eye.layer.cornerRadius = 17.0

        eye.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)


        let eye2 = UIView(frame: CGRect(x: 60, y: 10, width: 30.0, height: 30.0))

        eye2.layer.cornerRadius = 17.0

        eye2.backgroundColor = UIColor(red: 10, green: 10, blue: 10, alpha: 0.5)

        face.addSubview(eye)

        face.addSubview(eye2)

        return face

    }(1, 2, 3)


    func speak() {

        print("Hello, world")

    }

}


let h1 = human()


+ Recent posts