전 포스팅(브런치 쓰고 블로그로 옮김) 이후,
갓 졸업한 대학생(지인)이 스냅 킷에서 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()
'3D world > Unreal Engine Games Review' 카테고리의 다른 글
헥사 코드로 컬러 설정하기 (0) | 2019.01.12 |
---|---|
master cell customizing : master detail view (0) | 2019.01.12 |
싱글톤은 최소 2개 이상 (0) | 2019.01.12 |
한번에 여러개의 UIControl 속성을 지정하고 싶을 때 (0) | 2019.01.12 |
JAVA C/C++ Objective-C Swift (0) | 2019.01.02 |
최근댓글