Escaping Closure
(์ด์ค์ผ์ดํ ํด๋ก์ )
์ด์ค์ผ์ดํ ํด๋ก์ ๋
ํด๋ก์ ๊ฐ ํจ์ ์ธ์๋ก ์ ๋ฌ๋์ ๋, ํจ์์ ์คํ์ด ์ข
๋ฃ๋ ํ์ ์คํ๋๋ ํจ์์์!
(์์.. ํด๋ก์ ๋ ์ด๋ ค์ด๋ฐ, ์ด์ค์ผ์ดํ ํด๋ก์ ๋ ๋ ๋ชจ์ผ??๐ก
์ถ์์ต๋๋ค..ํํํ)
๊ทธ๋ฆฌ๊ณ ๋ฐ๋๋ก Non-escaping Closure๋ ์์ด์.
์ด๋
์์ ํจ์๊ฐ ์ข
๋ฃ๋๊ธฐ ์ ์ ์คํ๋๋ ํด๋ก์ ์
๋๋ค!
์ด์ ์ฐจ๊ทผ์ฐจ๊ทผ ์์๋ฅผ ๋ค์ด ์ ๋ฆฌํด๋ณผ๊ฒ์!!
func escapingClosureEX(completion: () -> Void) {
completion()
}
์ด์ ์ด๋ฐ ํํ๋ ํด๋ก์ ๋ผ๋ ๊ฑด ์ ์ ์์ฃ ?
ํด๋ก์ ์ ๊ฐ๋
์ ์์ง ๋ชจ๋ฅด์ ๋ค๋ฉด,
์ด๊ฑฐ ๋จผ์ ๋ณด๊ณ ์ค์์ฃ !๐
์. ๋ค์ ๋์์๋ณผ๊ฒ์.
func escapingClosureEX(completion: () -> Void) {
completion()
}
์ ์ฝ๋์์ completion์ ํ์
์ ๋งค๊ฐ๋ณ์๋ ์๊ณ ๋ฆฌํด ํ์
๋ ์๋ ํํ์
๋๋ค.
๊ทธ์น๋ง, ํด๋ก์ ๋ 1๊ธ ๊ฐ์ฒด๋ผ์ ๋ณ์๋ ์์์ ๋์
์ด ๊ฐ๋ฅํ๊ณ , ํ๋ผ๋ฏธํฐ ์ธ์๋ก ๋๊ฒจ์ค ์ ์์ฃ !
escapingClosureEX {
print("์คํธ!")
} // ์คํธ!
์ด๋ ๊ฒ ๋งค๊ฐ๋ณ์๋ก ํจ์๋ฅผ ๋๊ฒจ์ค ์ ์์ต๋๋ค!
์ ์ด์ ์ฌ๊ธฐ์ completion์ ์ ์ฅ๋ ํด๋ก์ ๋ฅผ 5์ด ๋ค์ ์คํ์ํค๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น์?
func escapingClosureEX(completion: () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
completion()
} // Error: Escaping closure captures non-escaping parameter 'completion'
}
์ด๋ ๊ฒ ํ๋ฉด ๋๊ฒ ์ฃ ?
๊ทผ๋ฐ..
์ด๋ฐ error๊ฐ ๋น๋๋ค..
์ด์ ๊ฐ ๋ญ๊น์??๐ค
ํค์๋ ์์ด ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๋ ํด๋ก์ ๋ ๋ชจ๋
์์์ ์ธ๊ธํ๋ Non-escaping closure ์
๋๋ค.
์ฆ, 5์ด ๋ค์ completion ํด๋ก์ ๊ฐ ์คํ๋๊ฒ ์ฝ๋๋ฅผ ์ผ์ง๋ง,
ํจ์๊ฐ ์ข
๋ฃ๋จ๊ณผ ๋์์ ํด๋ก์ ๋ ํจ๊ป ์ข
๋ฃ๋ ๊ฑฐ์ฃ ..
๊ทธ๋์ ํจ์์ ํ๋ฆ์์ ๋ฒ์ด๋ ํธ์ถ๋์ด์ผํ๊ธฐ ๋๋ฌธ์
"completion์ Non-escaping parameter์ผ!!"๋ผ๊ณ ์ปดํ์ผ๋ฌ๊ฐ ์๋ ค์ค๊ฑฐ์์.
์!! ๋ค์ ์ ๋ฆฌํด๋ณด์๋ฉด,
completion์ Non-escaping Closure(๋ง ๊ทธ๋๋ก ํ์ถ์ด ๋ถ๊ฐ๋ฅํ ํด๋ก์ )๋ผ์
ํจ์๊ฐ ์ข
๋ฃ๋๊ณ ๋ ํ์ ํด๋ก์ ๊ฐ ์คํ๋ ์ ์์ต๋๋ค.
๊ทธ๋์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ @escaping ํค์๋๋ฅผ ์ฌ์ฉํด์ฃผ์ด์ผ ํฉ๋๋ค.
<Non-escaping Closure>
1. ํจ์ ๋ด๋ถ์์ ์ง์ ์คํํ ๋๋ง ์ฌ์ฉ
2. ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ ํด๋ก์ ๋ ์์๋ ๋ณ์์ ๋์
ํ ์ ์์
error๊ฐ ๋ฐ์ํ๋๊น!
completion()์ ์ง์ฐ๊ณ , print๋ฌธ์ ๋ฃ์ด์ ํ๋ฆ์ ํ ๋ฒ ์ดํด๋ด
์๋ค.
func escapingClosureEX(completion: () -> Void) {
print("1")
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
print("2")
}
print("3")
}
escapingClosureEX {
}
print("4")
/*
1
3
4
2
*/
์ ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด,
์ด๋ ๊ฒ 1, 3, 4๊ฐ ๋จผ์ print ๋๊ณ , 2๊ฐ print ๋๊ณ ์์ต๋๋ค.
@escaping ํค์๋๋ฅผ ์ฌ์ฉํ์ง ์์์ง๋ง,
ํจ์ ๋ด๋ถ์์ 5์ด ๋ค์ ์คํ๋๋ asyncAfter๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์
ํจ์์ ์๋ช
์ฃผ๊ธฐ๊ฐ ๋๋ ํ์๋ ์คํ๋ ๊ฒ๋๋ค.
๊ทธ๋ผ..
ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ ํด๋ก์ ๋ฅผ ๋น๋๊ธฐ๋ก ์ฌ์ฉํ๊ณ ์ถ์ ๋ & ํจ์์ ํ๋ฆ์์ ํ์ถํ๊ณ ์ถ์ ๋
์ด๋ป๊ฒ ํด์ผํ ๊น์?๐ค
๋ฐ๋ก ์์์ ์ธ๊ธํ๋ @escaping ํค์๋๋ฅผ ์ฌ์ฉํด์ฃผ๋ฉด ๋ฉ๋๋ค!!
๊ณต๋ถํ๋ฉด์, (completion: @escaping ~~) ์ด๋ ๊ฒ ์๊ธด ๊ฑฐ ๋ณธ ์ ์์ผ์ ๊ฐ์?
์ด๊ฒ ๋ฐ๋ก Escaping Closure ์
๋๋ค!
completion์ ํ์
์ @escaping์ ๋ถ์ฌ์ Escaping Closure(์ด์ค์ผ์ดํ ํด๋ก์ )๋ผ๋ ๊ฒ์ ๋ช
์ํด ์ฃผ๋ ๊ฒ๋๋ค.
๋ถ์ด๋ ์๊ฐ
'์ด ํด๋ก์ ๋ ํจ์ ์คํ์ ํ๋ฆ๊ณผ ์๊ด์์ด ์ข
๋ฃ๋ ์ดํ์๋ ์คํ๋๋ ๋
์์ด์ผ!'๋ผ๊ณ ๋งํด์ฃผ๋ ๊ฑฐ์ฃ ใ
ใ
func escapingClosureEX(completion: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
completion()
}
}
์! ์๊น ์๋ฌ ๋ฐ์ํ๋ ์ฝ๋์์ @escaping ํค์๋๋ฅผ ๋ฃ์ด์คฌ๋๋
์ด์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์ฃ ?
@escaping ํค์๋๋ ์ฃผ๋ก ์ฝ๋ฐฑ ํจํด์ ์ฌ์ฉ๋๊ณ ,
๋น๋๊ธฐ ์์
์ด ์๋ฃ๋ ์ดํ์ ๊ฒฐ๊ณผ๋ฅผ ํด๋ก์ ๋ฅผ ํตํด ๋ฐํํด ์ค๋๋ค.
escapingClosureEX {
print("(5์ด ๋ค) ์ง !")
}
print("ํจ์ ๋!")
/*
ํจ์ ๋!
(5์ด ๋ค) ์ง !
*/
์คํํด๋ณด๋ฉด,
completion์ด ์ ์คํ๋ฉ๋๋ค!!
๊ทธ๋ผ ์ด Escaping Closure๋ ์ธ์ ํ์ฉํ๊ฒ ๋ ๊น์?
์ ๋ ์ด๋ฒ ํ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์ ๋ง๋๊ฒ ๋์ต๋๋ค..ใ
์ํ ๊ฒ์ ํ์ด์ง๋ฅผ ๋ด๋นํ์๋๋ฐ,
1. ๊ฒ์์ด๋ฅผ ์
๋ ฅํ์ง ์์์ ๊ฒฝ์ฐ
2. ๊ฒ์์ด์ ํด๋นํ๋ ์ํ๊ฐ ์๋ ๊ฒฝ์ฐ
์ด ๋ ๊ฐ์ง ๊ฒฝ์ฐ์ Label๋ก ๋ฌธ๊ตฌ๋ฅผ ๋ฃ์ด์ฃผ๊ณ ์ถ์์ต๋๋ค.
๊ทธ๋์ URLSession์ผ๋ก data๋ฅผ ๋ฐ์์ค๋ ํจ์์์
if ๋ฌธ์ ํ์ฉํด์
'๊ฒ์์ด ์์' & '์ด๋ฐ! ์ฐพ์ผ์๋ ์ํ์ด ์์ต๋๋ค.'
๋ผ๋ ๋ฌธ๊ตฌ๊ฐ ๋์ค๋๋ก ์ฝ๋๋ฅผ ์งฐ์์ด์!
๊ทธ๋ฐ๋ฐ.. ์ด๋ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋๋!!๐คฏ๐ฑ๐คฏ๐ฑ
๋ฐ์ดํฐ๊ฐ ๋์ด์จ ์ดํ์ ํด๋น ์ฝ๋๊ฐ ์คํ๋์ด์ผ ํ๋๋ฐ,
๋ฐ์ดํฐ๊ฐ ๋์ด์ค๊ธฐ ์ , ๋์ด์จ ํ..
์คํ ์์๊ฐ ๋ง์ง ์์์
๋ฐ์ดํฐ๊ฐ ์๋๋ฐ๋ ๋ถ๊ตฌํ๊ณ ,
'์ด๋ฐ! ์ฐพ์ผ์๋ ์ํ์ด ์์ต๋๋ค.'๋ผ๋ ๋ฌธ๊ตฌ๊ฐ
์ํ ๋ชฉ๋ก๋ค ๋ค์ ํจ๊ป ๋์ค๋๊ฑฐ์์..
์ด๋ด ๋!! ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฐ๋ก Escaping Closure(์ด์ค์ผ์ดํ ํด๋ก์ )์
๋๋ค!!
์ด๋ ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ํจ์์
@escaping ํค์๋๋ฅผ ์ฌ์ฉํด์ฃผ๊ณ , ๋ฆฌํด๊ฐ์ ๋น์๋์ต๋๋ค.
๊ทธ๋ฐ ๋ค์
if ๋ฌธ์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ถ๋ถ์์!
escaping ํด๋ก์ ์์ ์กฐ๊ฑด๋ฌธ์ ๋ฃ์ด์ฃผ์์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด!!
getData()๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ํจ์๊ฐ ๋ชจ๋ ์๋ฃ๋ ํ์
์ด ์กฐ๊ฑด๋ฌธ์ ์คํ๋๋๋ก ์ฝ๋๋ฅผ ๋ฐ๊พผ๊ฑฐ์์.
์ฌ๊ธฐ์ UI์ ๊ด๋ จ๋ ๊ฑด main thread๊ฐ ๋ด๋นํด์ผํ๊ธฐ ๋๋ฌธ์
์์ ๊ฐ์ ์๋ฆผ์ด ๋ฐ๊ฒ๋๋ค.
์ด๊ฑด DispatchQueue.main.async{} ์์ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
('mainํํ
์ผ์ ์ํค๋ ๋ช
๋ น์ด'๋ผ๊ณ ์๊ฐํ์๋ฉด ๋ฉ๋๋ค.)
@escaping ํค์๋ ํ๋๋ก..
์ ๋๋ก ์๋ํ๋ ๊ฑธ ๋ณด๊ณ .. ๊ฒฝ์
ํ์ต๋๋ค..
๊ณต๋ถํ ๊ฒ ์ฐ๋๋ฏธ๊ตฌ๋.. ์ถ์์ด์..ใ
ใ
๐ฉ
escaping ํด๋ก์ ๋ฅผ ์ฌ์ฉํ๋ฉด, ์ด๋ฐ ๋ถ๋ถ๋ค์ ํด๊ฒฐํ ์ ์์ง๋ง!!
๋ฌธ์ ์ ๋ค๋ ์๋ค๊ณ ํด์.
1. ์ฝ๋ฐฑ ์ค์ฒฉ์ผ๋ก ์ธํด ์ฝ๋๊ฐ ๋ณต์กํด์ง ๊ฐ๋ฅ์ฑ ์์
2. ์๋ฌ ์ฒ๋ฆฌ๊ฐ ์ด๋ ค์์ง ์ ์์ด ์ฝ๋ฐฑ ๋ด์์ ๋ฐ์ํ๋ ๊ฐํ ์ฐธ์กฐ ์ํ์ ์ฃผ์ํด์ผํจ
์.. ๊ฐํ ์ฐธ์กฐ ์ํ์ ๋ ๋ญ์ผ..???
๋ค.. ๋ค์ ๊ฒ์๋ฌผ ์คํฌ๋ฅผ ์ํ ๋ก๋ฐฅ์ด์์ต๋๋ค.
๋ค์ ๊ฒ์๋ฌผ ์ฃผ์ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌํด์ฃผ๋ ์น๊ตฌ ARC ์
๋๋ค!!
์๋ง.. ๋ค์ ์ฃผ์ ์ ๋ฆฌํ ๊ฒ ๊ฐ์์..ใ
(์ด๋ ๊ฒ ๋ ํ ์ฃผ ๋ฐ๋ฆฌ๋ ARC..)
To be continue...โง
'Study > ํผ๊ณต' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[swift] ARC์ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ (0) | 2024.04.30 |
---|---|
[Swift] ๊ณ ์ฐจํจ์(map, filter, reduce) (6) | 2024.04.21 |
[Swift] Show Library ํ์ฉ (Navigation Bar, Label, Button, Text Field) (0) | 2024.04.07 |