[๋ฉด์ ์ง๋ฌธ] ์ค์ํํธ(Swift) 75๋ฌธ 75๋ต
์ค์ํํธ 100๋ฌธ 100๋ต์ ๋ชฉํ๋ก!
์๋ ์ ์ฅ์์ ๋ ๋นจ๋ฆฌ ์ ๋ฐ์ดํธ๋ฉ๋๋ค! ์๋ชป๋ ๋ต๋ณ์ด ์๋ค๋ฉด ์๋ ค์ฃผ์๊ณ , ๋ ๊ณต๋ถํ ๊ฑฐ๋ฆฌ๊ฐ ์๋ค๋ฉด 100๊ฐ์ ์ง๋ฌธ์ ์ฑ์ฐ๊ธฐ ์ํด ๋๊ธ์ด๋ PR๋ก ์๋ ค์ฃผ์ธ์!
1. ์ค์ํํธ์์ Extension์ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์? (What are Extensions used for in Swift?)
๐ก Extension์ ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ ํ์
์ ์๋ก์ด ๋ฉ์๋, ํ๋กํผํฐ, ์์ฑ์
๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์ ์ํด ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
๐ก ์ด๋ ์ ์ฅ ํ๋กํผํฐ๋ extension์ ์ ์ํ ์ ์๊ณ , ์ฐ์ฐ ํ๋กํผํฐ
๋ง ์ ์ํ ์ ์์ต๋๋ค.
๐ก ์๋ฉธ์(deinitializer)๋ ์ถ๊ฐํ ์ ์๊ณ ์์ฑ์๋ convenience init
๋ง ์ ์ํ ์ ์์ต๋๋ค.
๐ก ๊ตฌ์กฐ์ฒด์ ๊ฒฝ์ฐ์๋ ๊ธฐ์กด ๊ตฌ์กฐ์ฒด์์๋ ์์ฑ์๋ฅผ ์ง์ ๊ตฌํํ๋ฉด memberwise initializer
(๊ธฐ๋ณธ ์์ฑ์)๊ฐ ์ฌ๋ผ์ง์ง๋ง ๊ตฌ์กฐ์ฒด์ Extension์ ์์ฑ์๋ฅผ ์ ์ํ๋ฉด memberwise initializer
๊ฐ ์ฌ๋ผ์ง์ง ์์ต๋๋ค.
๐ก where
์ ์ฌ์ฉํ๋ฉด ํน์ ํ ์กฐ๊ฑด์ ๊ฐ์ง ํ์
์ ๋ํด์๋ง Extension์ ์ ์ฉํ ์ ์์ต๋๋ค.
// https://stackoverflow.com/questions/30746190/swift-where-array-extensions
// Idable ํ๋กํ ์ฝ์ ์ฑํํ๋ ํ์
์ ๋ฐฐ์ด๋ง ์ด Extension์ ์ฌ์ฉ๊ฐ๋ฅ
extension Array where Element : Idable {
func filterWithId(id : String) -> [Element] {
return self.filter { (item) -> Bool in
return item.id == id
}
}
}
2. Swift์ upcasting๊ณผ downcasting์ ์ฐจ์ด์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is the difference between Upcast and Downcast in Swift?)
๐ก ์๋ก ์์ ๊ด๊ณ์ ์๋ ํด๋์ค์์ ์์ ํด๋์ค๋ฅผ ๋ถ๋ชจ ํด๋์ค๋ก ํ์
์บ์คํ
ํ๋ ๊ฒ์ ์
์บ์คํ
์ด๋ผ๊ณ ํ๊ณ as
๋ฅผ ์ฌ์ฉํด์ ์
์บ์คํ
ํ ์ ์์ต๋๋ค.
๐ก ์ปดํ์ผ ํ์์ ์
์บ์คํ
์ด ๊ฐ๋ฅํ์ง ์ฌ๋ถ๊ฐ ํ๋ณ๋๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ์ด ๋๋ฉด ํญ์ ์ฑ๊ณตํฉ๋๋ค.
class Student {
let name: String
init(name: String) {
self.name = name
}
}
class HighSchoolStudent: Student {
let gpa: Double
init(name: String, gpa: Double) {
self.gpa = gpa
super.init(name: name)
}
}
let hun = HighSchoolStudent(name: "hun", gpa: 4.5)
let updacasted = hun as Student
print(hun.name, hun.gpa)
print(updacasted.name, updacasted.gpa) // compile error
๐ก ๋ค์ด์บ์คํ
๋ as ๋ฅผ ์ฌ์ฉํ์ง๋ง ๋ค์ด ์บ์คํ
์ ์คํจํ ์๋ ์๊ธฐ ๋๋ฌธ์ as?
๋ as!
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๐ก as!
๋ ๋ฐํ์์ ํ์
์บ์คํ
์ ํ๊ณ ๋ง์ฝ ํ์
์บ์คํ
์ ์คํจํ๋ฉด ๋ฐํ์ ์๋ฌ
๋ฅผ ๋ฐ์์ํต๋๋ค.
๐ก as?
๋ ๋ฐํ์์ ํ์
์บ์คํ
์ ํ๊ณ ๋ง์ฝ ํ์
์บ์คํ
์ ์คํจํ๋ฉด nil
์ ๋ฐํํฉ๋๋ค.
let donwcastedHun = hun as? HighSchoolStudent
print(donwcastedHun) // nil
let forcelyDowncCastedHun = hun as! HighSchoolStudent // runtime error
print(forcelyDowncCastedHun)
3. == ์ฐ์ฐ์์ === ์ฐ์ฐ์๋ ์ด๋ป๊ฒ ๋ค๋ฅธ๊ฐ์? (What’s the difference between == and ===?)
๐ก ==
์ฐ์ฐ์๋ ๊ฐ์ ๋น๊ตํ๋๋ฐ ์ฌ์ฉ๋๊ณ , ===
์ฐ์ฐ์๋ ์ฐธ์กฐ ๊ฐ์ ๋น๊ตํ๋๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
4. Dispatch Queue์ Serial Queue์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is a Serial Queue?)
๐ก ์ง๋ ฌ ํ(serial queue)๋ ์์ ์ ํ ๋ฒ์ ํ๋์ฉ ์ฒ๋ฆฌํ๋ ์์ ํ์ ๋๋ค. ์ง๋ ฌ ํ๋ ์ค๋ ๋์ ๋จผ์ ํ ๋นํ ์์ ์ด ์์ ํ ๋๋์ผ ํ์์ ๋๊ธฐ ์ค์ธ ๋ค์ ์์ ์ ์ค๋ ๋์ ์๋ก ํ ๋นํฉ๋๋ค.
5. let๊ณผ var์ ์ฐจ์ด๋ ๋ฌด์์ธ๊ฐ์? (What is the difference between let and var in Swift?)
๐ก let
์ ํ๋ฒ ํ ๋น๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ์์๋ฅผ ์ ์ธํ๊ธฐ ์ํ ๋ช
๋ น์ด์ด๊ณ , var
๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ๋ณ์๋ฅผ ์ ์ธํ๊ธฐ ์ํ ๋ช
๋ น์ด์
๋๋ค.
๐ก ์ฌ์ค Obejctive-C ๊ด์ ์์ let
์ ์ฃผ์์ ๋ํ ํฌ์ธํฐ๋ฅผ ๋ฐ๊ฟ ์ ์๋ค๋ ์๋ฏธ์
๋๋ค. ์ด ๋๋ฌธ์ ํด๋์ค ์ธ์คํด์ค์ var๋ก ์ ์ธ๋ ๋ณ์์ ๊ฐ์ ๋ฐ๊พธ๋ ๊ฒ์ ๊ฐ๋ฅํฉ๋๋ค.
let hun = Student(name: "hun")
hun.name = "hunihun965"
print(hun.name) // hunihun956
6. function๊ณผ method์ ์ฐจ์ด๋ฅผ ๋งํด๋ณด์ธ์. (What are the differences between functions and methods in Swift?)
๐ก function์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋ ๋ธ๋ก์ ์๋ฏธํ๊ณ , method๋ ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์ ํฌํจ๋๋ function์ ์๋ฏธํฉ๋๋ค.
7. ์ปค์คํ ๊ฐ์ฒด์ ๋ฐฐ์ด์ด ์์ ๋, ํ๋กํผํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฐฐ์ด์ ์ด๋ป๊ฒ ์ ๋ ฌํ ์ ์์๊น์? (How to sort array of custom objects by property value in Swift?)
๐ก sorted ๋ฉ์๋์ ์ง์ ์ํ ํด๋ก์ ๋ฅผ ์ง์ ํด์ค ์ ์์ต๋๋ค.
struct Node {
let id: Int
}
let array = [
Node(id: 5),
Node(id: 4),
Node(id: 3),
Node(id: 2),
Node(id: 1)
]
let sorted = array.sorted(by: { $0.id < $1.id })
print(sorted)
// [PS.Node(id: 1), PS.Node(id: 2), PS.Node(id: 3), PS.Node(id: 4), PS.Node(id: 5)]
8. mutaing ํค์๋์ ์๋ฏธ๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What does the Swift mutating keyword mean?)
๐ก ์ค์ํํธ์์ ๊ฐ ํ์
ํ๋กํผํฐ๋ค์ ์ธ์คํด์ค ๋ฉ์๋์ ์ํด ์์ ๋ ์ ์์ต๋๋ค
.
๐ก mutaing ํค์๋๋ฅผ ๋ฉ์๋ ์์ ๋ถ์ด๋ฉด ๊ตฌ์กฐ์ฒด๋ ์ด๊ฑฐํ ์ธ์คํด์ค์์ ํ๋กํผํฐ๋ฅผ ์์ ํ ์ ์๊ฒ ๋ฉ๋๋ค.
๐ก mutating ํค์๋๊ฐ ๋ถ์ ๋ฉ์๋๋ฅผ ์คํํ๋ฉด ์ค์ํํธ๋ ์๋ก์ด ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑ
ํด ๋ณ๊ฒฝ๋ ํ๋กํผํฐ์ ๊ฐ์ ํ ๋นํ๊ณ ๋ฐํํด ํ์ฌ ๊ตฌ์กฐ์ฒด๋ฅผ ๋์ฒดํฉ๋๋ค. ๊ตฌ์กฐ์ฒด์ ๋ถ๋ณ์ฑ์ ์งํค๊ธฐ ์ํด ์ด๋ฐ ๋ฐฉ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.
9. ํ๋กํ ์ฝ๊ณผ ํด๋์ค์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What’s the difference between a protocol and a class in Swift?)
๐ก ํด๋์ค๋ ์ธ์คํด์ค ๋ฉ์๋์ ์ค์ ๊ตฌํ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ง๋ง ํ๋กํ ์ฝ์ ๋ฉ์๋์ ์ธํฐํ์ด์ค
๋ง ๊ฐ์ง๊ณ ์์ต๋๋ค. ํ๋กํ ์ฝ์ด ๊ตฌํ์ฒด๋ฅผ ๊ฐ์ง๊ฒ ํ๋ ค๋ฉด ํ๋กํ ์ฝ์ Extension
์ ๋ง๋ค์ด ๊ตฌํ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
10. Enum์์ raw value์ associated value์ ๋ํด ์ค๋ช ํด๋ณด์ธ์. (In Swift enumerations, what’s the difference between raw values and associated values?)
๐ก raw value
๋ ์์๊ฐ์ผ๋ก ์ด๊ฑฐํ์ ๋ชจ๋ case๋ค์ด ๋์ผํ ํ์
์ ๊ฐ์ง๊ณ ํ๋์ ๊ฐ๋ง ๊ฐ์ง ์ ์์ต๋๋ค.
๐ก ๋ฐ๋ฉด์ associated value
๋ ํํ์ ํตํด ๊ฐ case๋ค์ด ๋ค๋ฅธ ํ์
์ ๊ฐ์ง๊ฒ ํ ์๋ ์๊ณ , named tuple๋ก ์ด๋ฆ์ ๋ถ์ผ ์๋ ์์ผ๋ฉฐ, ์ฌ๋ฌ๊ฐ์ ๊ฐ์ ๊ฐ์ง๊ฒ ํ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
// associated values
enum Fruits {
case apple(origin: String, cost: Double)
case grape(origin: String, cost: Double, size: Double)
case orange(color: String)
}
let apple: Fruits = .apple(origin: "Korea", cost: 1000)
let grape: Fruits = .grape(origin: "Korea", cost: 100, size: 10)
let orange: Fruits = .orange(color: "Orange")
// raw values
enum Numbers: Int {
case one = 1
case two, three, four
}
print(Numbers.one.rawValue) // 1
print(Numbers.two.rawValue) // 2
print(Numbers.three.rawValue) // 3
11. inout์ ์ธ์ ์ฌ์ฉํ๋ฉด ์ข์๊น์? (What is a good use case for an inout parameter?)
๐ก inout
ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ ํ์
๋ณ์๊ฐ ์ ์ฅ๋ ์ฃผ์์ ๊ฐ์ ํจ์ ์๊ณผ ๋ฐ์์ ๋์ผํ๊ฒ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ํจ์๊ฐ ์
๋ ฅ๊ณผ ๋์ผํ ์ถ๋ ฅ์ ์ ๊ณตํ๊ณ , ํจ์ ๋ด์์ ์ ์ฉ๋ ๋ณ๊ฒฝ์ฌํญ์ด ํจ์ ์ธ๋ถ์์๋ ๋์ผํ๊ฒ ์ ์ฉ๋์ด์ผํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ก Swap์ ์ง์ ๊ตฌํํ๊ณ ์ ํ๋ค๋ฉด inout์ด ์ข์ ์ ํ์ด ๋ ์ ์์ต๋๋ค.
// https://stackoverflow.com/questions/62266178/swift-function-that-swaps-two-values
func swap<T>(a: inout T, b: inout T) {
(a, b) = (b, a)
}
var a = 0, b = 1
swap(a: &a, b: &b)
12. ์ฐ์ฐ ํ๋กํผํฐ์ ํด๋ก์ ๋ฅผ ๊ฐ์ง๋ ์ ์ฅ ํ๋กํผํฐ์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What is the difference between a computed property and a property set to a closure?)
๐ก ํด๋ก์ ๋ฅผ ๊ฐ์ง๋ ์ ์ฅ ํ๋กํผํฐ๋ ํ๋กํผํฐ์ ์์ฑ์์ ์ ํด๋ก์ ๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํฉ๋๋ค.
๐ก ๋ํ var ํค์๋๋ก ์์ฑ๋์ด ์๋ค๋ฉด ๋ค๋ฅธ ํด๋ก์ ๋ฅผ ํ ๋นํด์ฃผ๋ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
๐ก ์ฐ์ฐ ํ๋กํผํฐ๋ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ ๋๋ง๋ค
ํด๋ก์ ๋ฅผ ์์ฑํ๊ณ ์คํํฉ๋๋ค.
13. as? ์ as! ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What is difference between as?, as! and as in Swift?)
๐ก as? ์ as! ๋ชจ๋ ๋ฐํ์์ ๋ค์ด ์บ์คํ
์ ์ํด ์ฌ์ฉ๋์ง๋ง as?
๋ ์บ์คํ
์ ์คํจํ์ ๋ nil์ ๋ฐํํ๊ณ as!
๋ ๋ฐํ์ ์๋ฌ๋ฅผ ๋ฐ์์ํต๋๋ค.
14. ๋ฉ์๋ ์์์ ์ธ์ self๋ฅผ ์ฌ์ฉํด์ผํ ๊น์? (When would you use self in a method?)
๐ก ํ๋ผ๋ฏธํฐ์ ์ด๋ฆ์ด ์ธ์คํด์ค์ ํ๋กํผํฐ ์ด๋ฆ๊ณผ ๊ฒน์น ๊ฒฝ์ฐ์ ์ธ์คํด์ค์ ํ๋กํผํฐ์์ ๋ช
์
ํ๊ธฐ ์ํด์ self๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
15. Class์ Struct์ ๊ณตํต์ ๊ณผ ์ฐจ์ด์ ์ ์ค๋ช ํด๋ณด์ธ์. (What Classes and Structs have in common in Swift and what are their differences?)
๐ก Class ์ Struct ๋ชจ๋ ํ๋กํผํฐ๋ฅผ ์ ์ํด ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด ๊ฐ์ฒด์ ํํ
๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ก Class ์ Struct ๋ชจ๋ ํ๋กํ ์ฝ์ ์ฑํ
ํ ์ ์์ต๋๋ค.
๐ก Class ๋ ์ฐธ์กฐ ํ์
์ด์ง๋ง Struct๋ ๊ฐ ํ์
์
๋๋ค.
๐ก Class ๋ ์ฐธ์กฐ ํ์
์ด๊ธฐ ๋๋ฌธ์ ์ต์ ํ๋ฅผ ์ฌ์ฉํ์ง ์์ง๋ง ๊ตฌ์กฐ์ฒด๋ ๊ฐ ํ์
์ ๋ณต์ฌ๋ฅผ ์ต์ ํํ๊ธฐ ์ํด์ Copy-On-Write
๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ค์ ๋ก ๋ณ๊ฒฝ์ด ์ผ์ด๋๊ธฐ ์ ๊น์ง๋ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ค๋ฅธ ๋ณ์์ ํ ๋นํ๋๋ผ๋ ๊ฐ์ ์ฃผ์์ ๊ตฌ์กฐ์ฒด๋ฅผ ๊ณต์ ํ๋ค๊ฐ ๋ณ๊ฒฝ์ด ๋ฐ์ํ๋ฉด ์๋ก์ด ์ฃผ์์ ์ธ์คํด์ค๋ฅผ ์์ฑํด ํ ๋นํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๐ก Class ๋ ํ ์์ต
์ ์ธ์คํด์ค๋ฅผ ์ ์ฅํ๊ณ ์ธ์คํด์ค์ ์ฃผ์๊ฐ์ ์คํ ์์ญ์ ์ ์ฅํฉ๋๋ค. ๋ฐ๋ฉด์ Struct๋ ์คํ ์์ญ
์ ์ธ์คํด์ค๊ฐ ์ ์ฅ๋ฉ๋๋ค.
๐ก Class ๋ ์ธ์คํด์ค๋ผ๋ฆฌ์ ์์
์ด ๊ฐ๋ฅํ์ง๋ง Struct๋ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ๋์ ํ๋กํ ์ฝ
์ ํตํด ์์์ ๋์์ ๊ตฌํํ ์๋ ์์ต๋๋ค.
16. ๊ฐํ ์ฐธ์กฐ๋ ๋ฌด์์ด๊ณ ์ ํ์ํ๊ฐ์? (What’s a strong reference, and why do we need it?)
๐ก ๊ฐํ ์ฐธ์กฐ๋ ์ฐธ์กฐ ํ์
์ธ์คํด์ค๋ฅผ ๋ณ์์ ํ ๋นํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ค์ํํธ์ ARC๋๊ฐํ ์ฐธ์กฐ์ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ฆ๊ฐ
์ํค๊ณ , ๊ฐํ ์ฐธ์กฐ๊ฐ ํด์ ๋๋ฉด ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ๊ฐ์์ํต๋๋ค.
๐ก ์ฐธ์กฐ ์นด์ดํธ๊ฐ 0์ด ๋๋ฉด ๋ฉ๋ชจ๋ฆฌ์์ ์ธ์คํด์ค๋ฅผ ํด์
ํฉ๋๋ค.
๐ก ๋ฐ๋ผ์ ๊ฐํ ์ฐธ์กฐ๊ฐ ์์ด์ผ๋ง ์ค์ํํธ์์ ์ฐธ์กฐ ํ์
์ ์ธ์คํด์ค๋ฅด ๋ฉ๋ชจ๋ฆฌ์ ์ ์งํ ์ ์์ต๋๋ค.
17. strong, weak, unowned reference๋ ๊ฐ๊ฐ ์ธ์ ์ฌ์ฉํ ๊น์? (When to use strong, weak and unowned references?)
๐ก ๋ฉ๋ชจ๋ฆฌ์์ ์ธ์คํด์ค๊ฐ ํด์ ๋๋ ๊ฒ์ ๋ง๊ธฐ ์ํด ๊ฐํ ์ฐธ์กฐ์ธ strong reference
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. strong reference๋ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ 1 ์ฆ๊ฐ
์ํค๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐธ์กฐ์ ๋ฐฉํฅ์ด ๋จ๋ฐฉํฅ์ผ๋ก ์ด๋ฃจ์ด์ง๋ฉด strong reference๋ ํญ์ ์์ ํฉ๋๋ค.
๐ก weak reference
๋ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ฆ๊ฐ์ํค์ง ์์ต๋๋ค
. weak reference๋ ํญ์ var ๋ก ์ ์ธ๋๋ ์ต์
๋ ํ์
์ด ๋์ด์ผํฉ๋๋ค. weak์ผ๋ก ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ ํด์ ๋ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์ํ ์ฐธ์กฐ์ ๊ฐ๋ฅ์ฑ์ด ์๋ ์ํฉ์์ weak์ ํตํด ๋ฐฉ์งํ ์ ์์ต๋๋ค.
๐ก unowned reference
๋ weak ๊ณผ ๋์ผํ๊ฒ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ฆ๊ฐ์ํค์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋์์ unowned ๋ก ์ ์ธ๋ ๋ณ์๋ nil์ ๊ฐ์ง ์ ์๋ค
๋ ํน์ง์ด ์์ต๋๋ค. unowned ๋ก ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ ํด์ ๋๋ฉด unowned ๋ nil์ด ์๋๋ผ ๋ ์ด์ ์ฐธ์กฐํ ์ ์๋ ์ฃผ์๋ฅผ ๊ณ์ ์ฐธ์กฐํ๊ฒ ๋๊ณ unowned ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ ค๊ณ ํ๋ฉด ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฐ๋ผ์ unowned๋ ํด๋น ๋ณ์๊ฐ ์ฐธ์กฐํ๋ ์ธ์คํด์ค๋ณด๋ค ๋จผ์ ํด์ ๋๋ ๊ฒ์ด ํ์คํ ์ํฉ์์๋ง ์ฌ์ฉ
ํด์ผ ํฉ๋๋ค. Optional์ด ์๋๊ธฐ ๋๋ฌธ์ ์บก์ณ ๋ฆฌ์คํธ๋ ์ต์
๋ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ์ง ์์๋ ๋๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
18. Array, Set, Dictionary์ ์ฐจ์ด์ ์ด ๋ญ๊น์? (What's the main difference between the Array, Set and Dictionary collection type?)
๐ก Array๋ ๋ฆฌ์คํธ ์ปฌ๋ ์
์ผ๋ก Random Access
๊ฐ ๊ฐ๋ฅํด ์ธ๋ฑ์ค๋ฅผ ํตํด ์์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
๐ก Set์ Hashable ํ๋กํ ์ฝ์ ์ฑํ
ํ๋ ๊ฐ์ ์ ์ฅํด ์ค๋ณต๋์ง ์์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ์ฝ๋ ์
์
๋๋ค. ์์๊ฐ ๋ณด์ฅ๋์ง ์์ผ๋ฉฐ, ๊ต์งํฉ, ์ฐจ์งํฉ ๋ฑ ์งํฉ ์ฐ์ฐ์ ๋ฉ์๋๋ก ์ ๊ณตํฉ๋๋ค.
๐ก Dictionary ๋ Key-Value
ํํ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ์ฝ๋ ์
์
๋๋ค. ๋์
๋๋ฆฌ์ Key๋ก ์ฌ์ฉ๋ ํ์
์ Hashable ํ๋กํ ์ฝ์ ์ฑํ
ํ๊ณ ์ค๋ณต๋ ํค๋ฅผ ํ์ฉํ์ง ์์ผ๋ฉฐ ์์๋ฅผ ๋ณด์ฅํ์ง ์์ต๋๋ค.
19. required ํค์๋์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What does the required keyword in Swift mean?)
๐ก required
ํค์๋๊ฐ ๋ถ์ ํด๋์ค์ ์์ฑ์๋ ํด๋น ํด๋์ค๋ฅผ ์์๋ฐ๋ ์์ ํด๋์ค๊ฐ ํด๋น ์์ฑ์๋ฅผ ๋ฐ๋์ ๊ตฌํํ๋๋ก ๊ฐ์ ํฉ๋๋ค.
๐ก required ์๋ override
ํค์๋์ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์๊ธฐ ๋๋ฌธ์ override๋ฅผ ์๋ตํ๊ณ ๊ตฌํํ ์ ์์ต๋๋ค.
20. Self์ self์ ์ฐจ์ด๊ฐ ๋ญ๊น์? (What's the difference between Self vs self?)
๐ก self
๋ ํ์ฌ ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํต๋๋ค.
๐ก Self
๋ ํ๋กํ ์ฝ์์ ์ฌ์ฉ๋๋ฉด ํ๋กํ ์ฝ์ ์ฑํํ๋ ํ์
์ ์๋ฏธํ๊ณ , ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์์ ์ฌ์ฉ๋๋ฉด ์ค์ ์ ์ธ์ ์ฌ์ฉ๋ ํ์
์ ์๋ฏธํฉ๋๋ค.
class Superclass {
func f() -> Self { return self }
}
let x = Superclass()
print(type(of: x.f()))
// Prints "Superclass"
class Subclass: Superclass { }
let y = Subclass()
print(type(of: y.f()))
// Prints "Subclass"
let z: Superclass = Subclass()
print(type(of: z.f()))
// Prints "Subclass"
-> MetaType์ ๋ํ ๊ณต๋ถ๊ฐ ํ์ํ ๊ฒ ๊ฐ์ต๋๋คใ ํท๊ฐ๋ฆฌ๋ค์..
21. Array๋ณด๋ค Set์ ์ฌ์ฉํ๋๊ฒ ๋ ์ข์ ๋๋ ์ธ์ ์ผ๊น์? (When to use a set rather than an array in Swift?)
๐ก ์์๊ฐ ์ค์ํ์ง ์๊ณ ๋ฐ์ดํฐ๋ฅผ ์ค๋ณต์์ด ๊ณ ์ ํ๊ฒ ๊ด๋ฆฌ
ํ ๋ Set์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค.
๐ก ํนํ, Set์ ์ญ์ , ์ฝ์
, ์กฐํ๋ฅผ ๋ชจ๋ O(1)์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์์๊ฐ ์ค์ํ์ง ์์ผ๋ฉด์ ์ญ์ ์ ์ฝ์
์ด ๋น๋ฒํ ๋
๋ Set์ด ๋ ์ข์ ์ ์์ต๋๋ค.
22. Trailing Closure์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is trailing closure syntax?)
๐ก ํจ์์ ์ธ์๋ก ๋ค์ด๊ฐ ํด๋ก์ ๋ฅผ ํจ์ ํธ์ถ ์ธ๋ถ๋ก ๋ถ๋ฆฌํด์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
๐ก trailing closure์ ํ๋ผ๋ฏธํฐ ๋ ์ด๋ธ์ ์๋ตํ ์ ์๊ณ , ๋ง์ฝ ํธ์ถํ๋ ํจ์์ ํ๋ผ๋ฏธํฐ๊ฐ ํด๋ก์ ๋ฟ์ด๋ผ๋ฉด ()
๋ ์๋ตํ ์ ์์ต๋๋ค.
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
}
23. @objc๋ ์ธ์ ์ฌ์ฉํ๋์? (When to use @objc attribute?)
๐ก @objc ๋ ์ค์ํํธ์ API๋ฅผ Objective-C ๋ฐํ์์ ์ฌ์ฉํ ์ ์๋๋ก ํ๊ธฐ์ํด ์ฌ์ฉํฉ๋๋ค.
24. deinit์ ์ธ์ ์ฌ์ฉํ ๊น์? (When should I use deinit?)
๐ก deinit
์ ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋๊ธฐ ์ง์ ์ ํธ์ถ๋ฉ๋๋ค. ์ธ์คํด์ค๋ฅผ ํด์ ํ๊ธฐ ์ ์ ์ ํ๋์ด์ผ ํ๋ ์์
์ด ์๋ค๋ฉด deinit์ ๊ตฌํํ ์ ์์ต๋๋ค.
25. DispatchQueue.main.async ์ DispatchQueue.main.sync ์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (Explain the difference between DispatchQueue.main.async and DispatchQueue.main.sync?)
๐ก ๋ ๋ฐฉ๋ฒ ๋ชจ๋ DispatchQueue์ ์์
์ ๋ฑ๋กํ๊ณ Main ์ค๋ ๋์์ ์์
์ด ์ํ๋๋๋ก ํฉ๋๋ค
.
๐ก DispatchQueue.main.async
๋ ์์
์ ๋ฑ๋กํ ๋ async ํ๊ฒ ๋ฑ๋กํ๊ธฐ ๋๋ฌธ์ ๋ฑ๋กํ ์์
์ด ๋๋๊ธธ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฑ๋ก ํ ๊ณง๋ฐ๋ก ๋ค์ ์ฝ๋๋ฅผ ์คํ
ํฉ๋๋ค.
๐ก DispatchQueue.main.sync
๋ ์์
์ ๋ฑ๋กํ ๋ sync ํ๊ฒ ๋ฑ๋กํ๊ธฐ ๋๋ฌธ์ ๋ฑ๋กํ ์์
์ด ๋๋ ๋ ๊น์ง ๋ค์ ์ฝ๋๋ก ์งํํ์ง ์์ต๋๋ค.
์ด๋ ์์
์ ๋ฑ๋กํ ์ค๋ ๋ ์ญ์ ๋ฉ์ธ ์ค๋ ๋๋ผ๋ฉด ์ค๋ ๋๊ฐ sync์ ์ํด ๋์์ ๋ฉ์ถ ์ํ์์ ๋ฉ์ธ์ค๋ ๋์ ํ์ ๋ฑ๋ก๋ ์์
์ด ํ ๋น๋ฉ๋๋ค. ๋ฉ์ธ ์ค๋ ๋๋ ํ์ ๋ฑ๋กํ๋ ์์
์ด ๋๋๊ธธ ๊ธฐ๋ค๋ฆฌ๊ณ , ๋์์ ๋ฉ์ธ ์ค๋ ๋์ ํ ๋น๋ ์์
์ ์คํ๋๊ธธ ๊ธฐ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์ ๋ฐ๋๋ฝ ์ํ
์ ๋น ์ง๊ฒ ๋ฉ๋๋ค.
26. Defer์ ๋ํด ์ค๋ช ํด๋ณด์ธ์. (Explain the defer usage in Swift)
๐ก defer
๋ ํด๋ก์ ์ ์ ์๋ ์ฝ๋๊ฐ ์ฝ์ด์ง ์ดํ์ ํจ์๊ฐ ๋๋๊ธฐ ์ ๋ง์ง๋ง์ ์คํ๋๋๋ก ํฉ๋๋ค.
func deferTest() {
print(1)
defer {
print("last")
}
print(2)
}
deferTest()
// 1
// 2
// last
๐ก defer ์ฝ๋๊ฐ ์คํ๋์ง ์์ผ๋ฉด ํจ์๊ฐ ๋๋๋ ํด๋ก์ ๋ ์คํ๋์ง ์์ต๋๋ค.
func deferTest() {
print(1)
return
defer {
print("last")
}
print(2)
}
deferTest()
// 1
๐ก ์ฌ๋ฌ๊ฐ์ defer๊ฐ ์คํ๋์๋ค๋ฉด ์ฝํ์ง ์ญ์์ผ๋ก ์คํ๋ฉ๋๋ค.
func deferTest() {
print(1)
defer {
print("last1")
}
defer {
print("last2")
}
defer {
print("last3")
}
print(2)
}
deferTest()
// 1
// 2
// last3
// last2
// last1
๐ก ์ค์ฒฉ๋ defer๋ ๋ฐ๊นฅ์ชฝ defer ๋ถํฐ ์คํ๋ฉ๋๋ค.
func deferTest() {
print(1)
defer {
print("last1")
defer {
print("last2")
defer {
print("last3")
}
}
}
print(2)
}
deferTest()
// 1
// 2
// last1
// last2
// last3
27. open๊ณผ public ํค์๋์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What is the difference between open and public keywords in Swift?)
๐ก open
๊ณผ public
ํค์๋ ๋ชจ๋ ์ธ๋ถ ๋ชจ๋์์์ ์ ๊ทผ๊น์ง ํ์ฉ
ํฉ๋๋ค.
๐ก open์ ํด๋์ค์์๋ง ์ฌ์ฉ
ํ ์ ์์ต๋๋ค.
๐ก open์ ์ธ๋ถ ๋ชจ๋์์ ํด๋์ค๋ฅผ ์์ํ๋ ๊ฒ๊ณผ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๊ฐ๋ฅํ์ง๋ง, public์ ์ธ๋ถ ๋ชจ๋์์์ ํด๋์ค ์์๊ณผ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ ์ ํ
ํฉ๋๋ค.
๐ก ๋์ผํ ๋ชจ๋ ๋ด์์๋ open๊ณผ public ๋ชจ๋ ํด๋์ค ์์๊ณผ ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
28. fileprivate์ ์ค๋ช ํ๊ณ ์ธ์ ์ฌ์ฉํ๋ฉด ์ข์์ง ์ด์ผ๊ธฐํด๋ณด์ธ์. (When to use fileprivate access modifier in Swift?)
๐ก fileprivate์ ๊ฐ์ ์์คํ์ผ ๋ด์์์ ์ ๊ทผ๋ง ํ์ฉ
ํฉ๋๋ค.
๐ก fileprivate์ธ ์ธ์คํด์ค๋ฅผ ํ ๋นํ๋ ๋ณ์๋ private์ด๊ฑฐ๋ fileprivate
์ผ๋ก ์ ๊ทผ์ด ์ ํ๋์ด์ผ ํฉ๋๋ค.
๐ก fileprivate์ธ ํด๋์ค๋ฅผ ์์ํ ๋๋ ์์๋ฐ๋ ํด๋์ค๊ฐ private์ด๊ฑฐ๋ fileprivate
์ด์ด์ผ ํฉ๋๋ค.
๐ก ๊ฐ์ ํ์ผ ๋ด๋ถ์์๋ง ์ฌ์ฉ๋๋ ํด๋์ค์ผ ๋ fileprivate๋ก ์ ํํ๋ฉด ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
29. fileprivate๊ณผ private์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What is the difference between fileprivate and private?)
๐ก fileprivate์ ๊ฐ์ ํ์ผ ๋ด๋ถ์ ์๋ค๋ฉด ์ ๊ทผ์ ํ์ฉํ์ง๋ง private์ ๊ฐ์ ํ์ผ์ ์์ด๋ private์ผ๋ก ์ ์ธํ ๋์์ ๊ตฌํ๋ถ ๋ด๋ถ
, ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ํ์ผ์ ์๋ ๋์ผํ ์ ์ธ์ Extension
์์์ ์ ๊ทผ๋ง ํ์ฉํฉ๋๋ค.
// A.swift
private class A {
public init() {}
private var data: String
}
extension A { // ๊ฐ์ ํ์ผ์ ์์ ๋๋ง ๊ฐ๋ฅ
func updateData(data: String) {
self.data = data
}
}
// A+External swift
extension A { // Error. Cannot find type 'A' in scope
func printExternal() {
print(self.data)
}
}
30. static func ์ class func์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What is the difference between static func and class func in Swift?)
๐ก static func, class func ๋ชจ๋ ํ์
๋ฉ์๋
์ด๊ธฐ ๋๋ฌธ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์๊ณ ํ์
์ ์ ๊ทผํด ํจ์๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
๐ก class func๋ ์ค๋ฒ๋ผ์ด๋ฉ
์ ํ์ฉํ์ง๋ง static func๋ ์ค๋ฒ๋ผ์ด๋ฉ์ ํ์ฉํ์ง ์์ต๋๋ค.
๐ก ์ค์ํํธ์์ ์ ์ผํ๊ฒ ์ง์ ์ ์ธ ์์์ ์ง์ํ๋ ๊ฐ์ฒดํ์
์ด ํด๋์ค๋ผ๋ ๊ฒ์ ์๊ฐํด๋ณด๋ฉด class๋ง ์ค๋ฒ๋ผ์ด๋ฉ์ ํ์ฉํ๋ ๊ฒ๊ณผ ์ฝ๊ฒ ์ฐ๊ฒฐ์ํฌ ์ ์์ต๋๋ค!
31. Function๊ณผ Closure์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What is the difference between functions and closures?)
๐ก Function๊ณผ Closure ๋ชจ๋ ์คํ๊ฐ๋ฅํ ์ฝ๋๋ธ๋ก์ ์๋ฏธํฉ๋๋ค.
๐ก Function์ func ํค์๋์ ํจ๊ป ์ ์ธ๋๊ณ ํจ์์ ์ด๋ฆ
์ ํญ์ ๊ฐ์ ธ์ผํฉ๋๋ค. ๋ฐ๋ฉด์ ํด๋ก์ ๋ ์ด๋ฆ์ ๊ฐ์ง์ง ์์ต๋๋ค.
32. ์ค์ํํธ์์ ์ถ์ ํด๋์ค๋ฅผ ๋ง๋ค๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น์? (Is there a way to create an abstract class in Swift?)
๐ก ์ค์ํํธ๋ ์ถ์ ํด๋์ค ๋ฌธ๋ฒ์ ์ง์ํ์ง๋ ์์ง๋ง ํ๋กํ ์ฝ์ ํตํด ๋์ผํ ๋์์ ํ๋๋ก ํ ์ ์์ต๋๋ค.
๐ก ํ๋กํผํฐ์ ๋ฉ์๋์ ์ํ์ ํ๋กํ ์ฝ์ ์ ์ธํด๋๊ณ , Extension
์ ํตํด ํ๋กํ ์ฝ ๋ฉ์๋์ ๊ธฐ๋ณธ ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด์ฃผ๋ฉด ์ถ์ํด๋์ค์ ๋์ผํ ๊ฐ๋
์ ๊ตฌํ์ ํ ์ ์์ต๋๋ค.
33. Any์ AnyObject์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์. (What’s the difference between Any and AnyObject?)
๐ก Any์ AnyObject ๋ชจ๋ ๋ฒ์ฉํ์
์ผ๋ก ์ฌ๋ฌ ํ์
์ ํ๋ฒ์ ํํํ ์ ์๊ฒ ํด์ฃผ์ง๋ง AnyObject๋ ํด๋์ค ํ์
๋ง
์ ์ฅํ ์ ์๋ค๋ ์ ํ์กฐ๊ฑด์ด ์ถ๊ฐ๋ฉ๋๋ค.
34. ์ธ์ ํด๋์ค ๋์ ๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์๊น์? (When should you use Structs over Classes?)
๐ก ์ค์ํํธ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ธธ ๊ถ์ฅํ๊ณ ์์ต๋๋ค.
๐ก ๊ตฌ์กฐ์ฒด๋ ๋ถ๋ณ์ฑ์ ์ ์งํ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ์ค๋ ๋๋ค์ด ํ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๋ ๋ค์ค ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์
ํ๊ฒ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
๐ก ๊ตฌ์กฐ์ฒด๋ ์คํ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๋ ๋น ๋ฆ
๋๋ค. ํ์ ์ ์ฅ๋๋ ํด๋์ค๋ ํ์ ์ธ์คํด์ค๋ฅผ ์ ์ฅํ๊ณ ๊ทธ ์ฐธ์กฐ๊ฐ์ ์คํ์ ์ ์ฅํฉ๋๋ค.
35. ์ธ์ ๊ตฌ์กฐ์ฒด ๋์ ํด๋์ค๋ฅผ ์ ํํด์ผํ ๊น์? (When should you use Classes over Structs?)
๐ก ๊ตฌ์กฐ์ฒด๋ ๊ฐ ํ์
์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ด ๊ฐ์ ์ธ์คํด์ค๊ฐ ๋งค๋ฒ ๋ณต์ฌ๋์ด ์ฌ์ฉ๋ฉ๋๋ค.
๐ก ๋ฐ๋ผ์ ๋ง์ฝ ์ด๋ค ์ธ์คํด์ค์ ์ฐธ์กฐ๊ฐ์ ๊ณ ์ ์ฑ์ ์ ์ง
ํ๊ณ ์ถ๋ค๋ฉด ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ก ๋ํ Objective-C์ API๋ฅผ ์ฌ์ฉํ ๋
๋ ํด๋์ค๊ฐ ๋ฐ๋์ ํ์ํ๊ธฐ๋ ํฉ๋๋ค. i.e.)NSCache์ value์๋ ๊ตฌ์กฐ์ฒด ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
36. weak๊ณผ unowned ์ ์ฐจ์ด๋ฅผ ์ค๋ช ํ๊ณ ์๋ฅผ ๋ค์ด์ฃผ์ธ์. (Explain the difference between weak and unowned references. Provide an example.)
๐ก weak์ ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ ํด์ ๋๋ ๊ฒ์ ์ผ๋ํ์ฌ ํญ์ Optionalํ ํ์
์ ๊ฐ์ง๋๋ค. ๋ง์ฝ weak์ผ๋ก ์ ์ธํ ๋ณ์๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋๋ฉด ํด๋น ๋ณ์์ ๊ฐ์ nil๋ก ์ฑ์์ง๋๋ค.
๐ก unowned๋ ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ unowned ๋ณ์ ์ด์ ์๋ ์ ๋ ํด์ ๋์ง ์์์ ๋ณด์ฅํ๋ ์ํฉ
์์ ์ฌ์ฉํฉ๋๋ค.
๐ก unwoend๋ Optional์ ํ์ฉํ์ง ์์ต๋๋ค
. ๋ฐ๋ผ์ unowned๊ฐ ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ ํด์ ๋ ์ดํ์ unowned ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ฉด ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
// https://stackoverflow.com/questions/24011575/what-is-the-difference-between-a-weak-reference-and-an-unowned-reference
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
}
// Person ===(strong)==> Apartment
// Person <==(weak)===== Apartment
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}
// Customer ===(strong)==> CreditCard
// Customer <==(unowned)== CreditCard
37. unowned๋ ์ธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ ํ ๊น์? (When is it safe to use an unowned reference?)
๐ก unowned๋ก ์ ์ธ๋ ๋ณ์๊ฐ ์ฐธ์กฐํ๋ ์ธ์คํด์ค๊ฐ ํด๋น unowned ๋ณ์๊ฐ ํด์ ๋ ์ดํ์ ํด์ ๋๋ ๊ฒ์ด ๋ณด์ฅ๋๋ ์ํฉ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ ํฉ๋๋ค.
// https://www.advancedswift.com/strong-weak-unowned-in-swift/
extension HomeVC {
// Calling loadAPI no longer creates a Retain Cycle:
// 1. Self (HomeVC) has a strong reference to api
// 2. api has a strong reference to completion
// 3. completion has a unowned reference to self (HomeVC)
func loadAPI() {
api.completion = { [unowned self] (data, error) in
self.hideLoadingIndicator()
}
}
// HomeVC -> api -> completion === (unonwned) ===> HomeVC
}
38. Swift์ Copy-on-Write์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is Copy on Write (Cow) in Swift?)
๐ก COW๋ ๊ฐ ํ์
์ ๋ณต์ฌ๋ฅผ ์ค์ ๋ก ๊ฐ์ด ์์ ๋๊ธฐ ์ ๊น์ง๋ ๋ฐ์์ํค์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ต์ ํ
ํ๋ ๋ฐฉ๋ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด์ ๊ฐํ์
์ธ ๋ฐฐ์ด์ ๋ ๋ณ์์ ์ ์ฅํด๋๋ฉด ๋ ๊ฐ์ ๋ค๋ฅธ ์ธ์คํด์ค๊ฐ ์์ฑ๋ ๊ฒ์ ๊ธฐ๋ํ์ง๋ง ์ค์ ๋ก๋ ์ฃผ์ ๊ฐ์ ๊ณต์ ํ๊ณ ์๋ค๊ฐ ๋ณ์์ ๋ณ๊ฒฝ์ฌํญ์ด ์๊ฒผ์ ๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ํ ๋นํฉ๋๋ค.
๐ก ์ด๋ ๊ฒ ํ๋ฉด ์์ ์ด ์ผ์ด๋์ง ์๋ ๊ฐ ํ์
๋ฐ์ดํฐ๋ ๋ณต์ฌ๋ณธ์ ๋ง๋ค์ง ์๊ณ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ต์ ํํ ์ ์์ต๋๋ค.
import Foundation
func address(of valueTypePointer: UnsafeRawPointer) -> Int {
return Int(bitPattern: valueTypePointer)
}
func compareValueTypeInstance(of arr1:[Int], with arr2:[Int]) {
if address(of: arr1) == address(of: arr2) {
print("same instance")
} else {
print("different istance")
}
}
let arr1 = [1, 2, 3, 4]
var arr2 = arr1
compareValueTypeInstance(of: arr1, with: arr2) // "same instance"
arr2.append(5)
compareValueTypeInstance(of: arr1, with: arr2) // "different istance"
39. staic ๋ณ์์ class ๋ณ์์ ๋ํด ์ค๋ช ํด๋ณด์ธ์. (What’s the difference between a static variable and a class variable?)
๐ก static ๋ณ์์ class ๋ณ์ ๋ชจ๋ ํ์
ํ๋กํผํฐ
๋ก ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ก ํ์
ํ๋กํผํฐ๋ lazy
ํ๊ฒ ๋์ํด์ ์ค์ ๋ก ๋ถ๋ฆฌ๊ธฐ ์ ๊น์ง๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋์ง ์์ต๋๋ค.
๐ก ํ์
ํ๋กํผํฐ๋ ํ ๋ฒ ๋ถ๋ฆฌ๋ฉด ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋๊ณ ๊ทธ ์ดํ๋ก๋ ์๋ก ์์ฑ๋์ง ์์ต๋๋ค
.
๐ก ํ์
ํ๋กํผํฐ๋ ํ์
์ด๋ฆ์ ํตํด์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ณ ์ด๊ธฐ๊ฐ์ ํญ์ ๊ฐ์ ธ์ผํฉ๋๋ค
.
๐ก class
๋ก ์ ์ธ๋ ํ์
ํ๋กํผํฐ๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๊ฐ๋ฅ
ํฉ๋๋ค.
๐ก ๋ฐ๋ฉด์ static
์ผ๋ก ์ ์ธ๋ ํ์
ํ๋กํผํฐ๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๋ถ๊ฐ๋ฅ
ํฉ๋๋ค.
40. ARC์ GC๋ ์ด๋ค ์ฐจ์ด์ ์ด ์๋์? (What is the difference between ARC (automatic reference counting) and GC (garbage collection)?)
๐ก ARC์ GC์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ ๋ฐํ์์ ์ฒ๋ฆฌ๋ฅผ ํ๋์ง, ์ปดํ์ผ ํ์์ ์ฒ๋ฆฌ๋ฅผ ํ๋์ง์ ์์ต๋๋ค. ARC
๋ Retain๊ณผ Release๋ฅผ ์ปดํ์ผ๋ฌ๊ฐ ์ปดํ์ผ ํ์
์ ์๋์ผ๋ก ์ฝ์
ํด Reference Count๋ฅผ ์กฐ์ ํฉ๋๋ค.
๐ก ๋ฐ๋ณ์ GC
๋ ๊ฐ๋น์ง ์ฝ๋ ํฐ๋ฅผ ๋ฐํ์
์ ๋ณ๋๋ก ์คํํ๋ฉด์ ๋ฉ๋ชจ๋ฆฌ์ ์ํ๋ฅผ ๊ฐ์ํฉ๋๋ค.
๐ก ARC๋ ๋จ์ํ ์นด์ดํ
์ ํตํด ์ธ์คํด์ค๋ค์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ํ์ฐธ์กฐ์ ์ํ์ด ์์ต๋๋ค.
๐ก GC๋ Mark-and-Sweep
๋ฐฉ์์ผ๋ก ๋ฃจํธ๋
ธ๋๋ถํฐ ๋๋ฌ ๊ฐ๋ฅํ ์ธ์คํด์ค๋ค์ ๋ชจ๋ ์ฒดํฌํฉ๋๋ค. ๋ฐ๋ผ์ ์ํ์ฐธ์กฐ๊ฐ ๋ฐ์ํ๋๋ผ๋ ๋ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๋ ์ธ์คํด์ค๊ฐ ํด์ ๋๋ฉด ๋ฃจํธ๋ก๋ถํฐ ์ํ์ฐธ์กฐ๊ฐ ๋ฐ์ํ ์ธ์คํด์ค๋ค์ ๋๋ฌํ ์ ์๋ ๊ฒฝ๋ก๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋ ์ธ์คํด์ค๋ฅผ ๋ชจ๋ ํด์ ํ ์ ์์ต๋๋ค.
41. autoclosure attribute์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is the autoclosure attribute and when to use it?)
๐ก autoclosure๋ ํด๋ก์ ๊ฐ ์๋ ์ฝ๋๋ฅผ ํจ์์ ์ธ์๋ก ๋ฐ์ ๋ ์ด ์ฝ๋๋ฅผ ํด๋ก์ ๋ก
๋ง๋ค์ด์ฃผ๋ ํค์๋์
๋๋ค.
๐ก autoclosure์ ์ฃผ๋ ๋ชฉ์ ์ ์ฝ๋์ ์คํ์ ์ง์ฐ
์ํค๊ธฐ ์ํจ์
๋๋ค. ํด๋ก์ ๋ฅผ ์ธ์๋ฅผ ๋๊ธฐ๋ ๊ฒ์ผ๋ก๋ ์ง์ฐ ์คํ์ ๋ง์กฑ์ํฌ ์ ์์ง๋ง autoclosure๋ฅผ ์ฌ์ฉํ๋ฉด ํธ์ถํ๋ ์ธก ์ฝ๋์ ๊ฐ๋
์ฑ์ด ์ข์์ง๋๋ค.
๐ก ํด๋ก์ ์ฌ์ฉ X
// https://www.avanderlee.com/swift/autoclosure/
struct Person: CustomStringConvertible {
let name: String
var description: String {
print("Asking for Person description.")
return "Person name is \(name)"
}
}
let isDebuggingEnabled: Bool = false
func debugLog(_ message: String) {
/// You could replace this in projects with #if DEBUG
if isDebuggingEnabled {
print("[DEBUG] \(message)")
}
}
let person = Person(name: "Bernie")
debugLog(person.description) // ๋๋ฒ๊น
๋ชจ๋๊ฐ ์๋์ด๋ person.description์ด ์คํ๋จ
๐ก ํด๋ก์ ์ฌ์ฉ
let isDebuggingEnabled: Bool = false
func debugLog(_ message: () -> String) {
/// You could replace this in projects with #if DEBUG
if isDebuggingEnabled {
print("[DEBUG] \(message())")
}
}
let person = Person(name: "Bernie")
debugLog({ person.description }) // ํด๋ก์ ๊ฐ ๋์ด๊ฐ๊ธฐ ๋๋ฌธ์ description ์ฐธ์กฐ๊ฐ ์คํ๋์ง ์์
๐ก autoclosure ์ฌ์ฉ
let isDebuggingEnabled: Bool = false
func debugLog(_ message: @autoclosure () -> String) {
/// You could replace this in projects with #if DEBUG
if isDebuggingEnabled {
print("[DEBUG] \(message())")
}
}
let person = Person(name: "Bernie")
debugLog(person.description) // ํด๋ก์ ๋ก ๋ํ๋๋ฉด์ ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ description ์ฐธ์กฐ๊ฐ ์คํ๋์ง ์์
42. GCD์ QoS์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is QoS (Quality of Service) in GCD?)
๐ก Qos ๋ DispatchQueue์ ๋ฑ๋กํ๋ ์์
์ ์ฐ์ ์์
๋ฅผ ๊ฒฐ์ ํ ์ ์๊ฒ ํฉ๋๋ค.
๐ก ์ฐ์ ์์๊ฐ ๋์ ์์
์ ์ฐ์ ์์๊ฐ ๋ฎ์ ์์
๋ณด๋ค ๋จผ์ ์คํ๋์ง๋ง ์ฑ์ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฌ์ฉํฉ๋๋ค.
๐ก qos ์์ค์ ๋ค์์ผ๋ก ์ ์๋ฉ๋๋ค.
๐ก userInterative
: ๊ฐ์ฅ ์ฐ์ ์์๊ฐ ๋์ต๋๋ค. UI์์
๋ฑ ์ฌ์ฉ์์๊ฒ ์ฆ๊ฐ์ ์ธ ๋ฐ์์ ํด์ผํ๋ ์์
์ ์ฌ์ฉํฉ๋๋ค.
๐ก userInitiated
: ๋ฌธ์๋ฅผ ์ด๋ํ๊ฑฐ๋ ์ธํฐํ์ด์ค์ ์ ์ค์ณ๋ฅผ ์ทจํ๋ ๋ฑ ์ฌ์ฉ์์์ ์ํธ์์ฉ์ด ์์๋์์ ๋ ๊ณง๋ฐ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผ ํ๋ ์์
์ ์ฌ์ฉํฉ๋๋ค.
๐ก default
: ๊ธฐ๋ณธ๊ฐ์
๋๋ค. ์ผ๋ฐ์ ์ธ ์์
์ ์ฌ์ฉํฉ๋๋ค.
๐ก utility
: ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฌ๋ก๋ ํ๋ ๋ฑ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์
์ ์ฌ์ฉํฉ๋๋ค. ํ๋ก๊ทธ๋์ค ๋ฐ๋ ์กํฐ๋นํฐ ์ธ๋์ผ์ดํฐ์ ํจ๊ป ์ฌ์ฉํฉ๋๋ค.
๐ก background
: ์ฌ์ฉ์๊ฐ ์ธ์งํ์ง ๋ชปํ๋ ์์ญ์์ ์๋์ง์ ๋ฆฌ์์ค๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
43. Hashable ํ๋กํ ์ฝ์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What is the use of Hashable protocol?)
๐ก Hashable ํ๋กํ ์ฝ์ ์ฑํํ๋ ํ์
์ ๋ชจ๋ ๊ฐ์ ์ ์์ธ ํด์๊ฐ
์ผ๋ก ํํํ ์ ์์ต๋๋ค.
๐ก ์ค์ํํธ์ ๊ธฐ๋ณธ ํ์
์ค ๋ฌธ์์ด, ์ ์, ์ค์, ๋ถ๋ฆฌ์ธ, ๊ทธ๋ฆฌ๊ณ Set ์ฝ๋ ์
์ด Hashable ํ๋กํ ์ฝ์ ์ฑํํ๊ณ ์์ต๋๋ค.
๐ก Hashable ํ๋กํ ์ฝ์ ์ฑํํ๋ ์ปค์คํ
ํ์
์ ์ ์ฅ ํ๋กํผํฐ๊ฐ ๋ชจ๋
Hashable ํ๋กํ ์ฝ์ ์ฑํํ๊ณ ์๋ค๋ฉด, ๋ณ๋ค๋ฅธ ๊ตฌํ์์ด Hashable ํ๋กํ ์ฝ์ ์ฑํํ๋ ๊ฒ ๋ง์ผ๋ก Hashableํ ๋์์ ์ ๊ณตํฉ๋๋ค.
๐ก ๊ทธ๋ ์ง ์๋ค๋ฉด ==
๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ hash(into:) ๊ตฌํํด์ ํด์๊ฐ์ ์์ฑํ๋๋ฐ ํ์ํ ํ๋กํผํฐ๋ฅผ ์ง์ ํด์ฃผ์ด์ผํฉ๋๋ค.
// https://developer.apple.com/documentation/swift/hashable
struct GridPoint {
var x: Int
var y: Int
}
extension GridPoint: Hashable {
static func == (lhs: GridPoint, rhs: GridPoint) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
func hash(into hasher: inout Hasher) {
hasher.combine(x)
hasher.combine(y)
}
}
44. Hashable ํ๋กํ ์ฝ์ ์ฑํํ๋ ์ปค์คํ ํ์ ์ด Equtable๋ ์ฑํํด์ผํ๋ ์ด์ ๊ฐ ๋ฌด์์ธ๊ฐ์?
๐ก ์ด๋ค ๊ฐ์ ๋ํ Hash ๊ฐ์ ๊ณ ์ ํ์ง๋ง, Hash ๊ฐ์ ์์ฑํ๋ built in ๋ฉ์๋์ธ hasher(_:) ๊ฐ ์๋ก ๋ค๋ฅธ ๊ฐ์ ๋ํด ๋์ผํ Hash ๊ฐ์ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๐ก ์ด๋ฐ ๊ฒฝ์ฐ๋ฅผ ํด์ ์ถฉ๋(Hash Collision)์ด๋ผ๊ณ ํ๊ณ , ํด์ ์ถฉ๋์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ๋ฅผ ์๊ธฐ ์ํด์๋ ๋ ์ธ์คํด์ค๊ฐ ๊ฐ์ด ์ผ์นํ๋ ํ์ธํด์ผํ๊ธฐ ๋๋ฌธ์ Equatable ํ๋กํ ์ฝ์ ์ฑํํด์ผํฉ๋๋ค.
Hashable์ ๋ํ ์์ฒญ ์ข์ ๊ธ์ด ์๋ค์! https://betterprogramming.pub/what-is-hashable-in-swift-6a51627f904
45. ์ด๊ฑฐํ๋ Hashable์ ์ฑํํ์ ๋ ์๋์ผ๋ก Hashableํ๊ฒ ๋ง๋ค ์ ์๋์?
๐ก ์ด๊ฑฐํ์ associated value
๊ฐ ์๋ ๊ฒฝ์ฐ์๋ Hashable ํ๋กํ ์ฝ๋ง ์ฑํํด๋ Hashableํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๐ก ํ์ง๋ง associated value๊ฐ ์๋ ๊ฒฝ์ฐ์๋ hash
๋ฉ์๋๋ฅผ ๊ตฌํํด์ฃผ์ด์ผ ํฉ๋๋ค.
46. init?()๊ณผ init()์ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์? (What’s the difference between init?() and init()?)
๐ก init?()์ ์คํจ๊ฐ๋ฅํ ์์ฑ์
๋ก ์์ฑ์์ ์ฝ๋๋ฅผ ์คํํ๋ค๊ฐ ๋ฌธ์ ๊ฐ ์๊ฒผ์ ๋ nil์ ๋ฐํํ๋๋ก ํ ์ ์์ต๋๋ค.
class A {
let a: String
init?(a: String) {
guard !a.isEmpty else { return nil }
self.a = a
}
}
print(A(a: ""))
print(A(a: "abc")?.a)
47. Never ๋ฐํ ํ์ ์ ๋ํด ์ค๋ช ํด๋ณด์ธ์. (What is the Never return type? When to use it over Void?)
๐ก Never ํ์
์ ๋น์ ์์ ์ธ ์ข
๋ฃ
์ ์ฌ์ฉ๋๋ ๋ฐํ ํ์
์ด๋ฉฐ ๊ฐ์ ์ง๋์ง๋ ์์ต๋๋ค.
๐ก ํด๋ก์ , ํจ์์ ์๋ฌ๋ฅผ throwํ๋ ๊ฒ์ผ๋ก ์ก์ ์ ์๋ ์ฌ๊ฐํ ์ค๋ฅ๊ฐ ์์์ ์๋ฆด ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
func crashAndBurn() -> Never {
fatalError("Something very, very bad happened")
}
48. weak๋ง ์ฌ์ฉํ์ง ์๊ณ unowned๋ ์ฌ์ฉํ๋ ์ด์ ๊ฐ ๋ฌด์์๊น์? (Why can not we just use weak everywhere and forget about unowned?)
๐ก unowned๋ฅผ ์ฌ์ฉํ๋ฉด ์ต์
๋
์ ์ ๊ฒฝ์ฐ์ง ์์๋ ๋๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
๐ก unowned๋ฅผ ์ฌ์ฉํ๋ฉด ์ฐธ์กฐํ๊ณ ์๋ ์ธ์คํด์ค๊ฐ unowned ํ๋กํผํฐ ์ด์ ์ ํญ์ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋๋ ๊ฒ์ ๋ช
์์ ์ผ๋ก ํํ
ํ ์ ์์ต๋๋ค.
49. ARC๊ฐ ๋ฉ๋ชจ๋ฆฌํด์ ๋ฅผ ํ ์ ์๋ ์ํฉ์ ๋ํด ์ค๋ช ํด๋ณด์ธ์. GC๋ ํด๊ฒฐํ ์ ์์๊น์? (Explain the use case when ARC won't help you to release memory (but GC will)?)
๐ก ARC๋ ๊ฐํ ์ํ ์ฐธ์กฐ ์ํฉ์์ ์ธ์คํด์ค๋ฅผ ํด์ ํ์ง ๋ชปํ๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ง์ฝ ์ด๋ค ๋ ํด๋์ค ์ธ์คํด์ค๊ฐ ํ๋กํผํฐ์ ์๋ก๋ฅผ ๊ฐํ ์ฐธ์กฐ
๋ก ์ ์ฅํ๊ณ ์์ ๋ ๊ฐํ ์ํ ์ฐธ์กฐ
๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
๐ก ์ํ์ฐธ์กฐ ๋ฐ์
class A {
var b: B?
deinit {
print("A deinitialzied")
}
}
class B {
var a: A?
deinit {
print("B deinitialzied")
}
}
var a = A()
var b = B()
a.b = b
b.a = a
a = A()
b = B()
// retain cycle
๐ก weak๋ก ์ํ์ฐธ์กฐ ํํผ
class A {
var b: B?
deinit {
print("A deinitialzied")
}
}
class B {
var a: A?
deinit {
print("B deinitialzied")
}
}
var a = A()
var b = B()
a.b = b
b.a = a
a = A()
b = B()
// B deinitialzied
// A deinitialzied
50. DispatchGroup์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (Explain what is DispatchGroup?)
๐ก DispatchGroup์ ์ฌ๋ฌ ์ค๋ ๋์ ๋ถ๋ฐฐ๋์ด ์๋ ์์
๋ค์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด์ ๋๊ธฐ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
๐ก DispatchGroup์ ์ถ๊ฐ๋ ๋ enter
๋ฉ์๋๋ฅผ ํตํด ์์
์ ๊ฐ์๋ฅผ 1 ๋๋ ค์ฃผ๊ณ , ์์
์ด ๋๋ ๋ DispatchGroup์์ ๋น ์ ธ๋์ค๋ฉด์ leave
๋ฉ์๋๋ฅผ ํตํด ์์
์ ๊ฐ์๋ฅผ ํ๋ ์ค์ฌ์ค๋๋ค.
๐ก ์์
์ ๊ฐ์๊ฐ 0์ด๋๋ฉด notify
๋ฉ์๋๊ฐ ์คํ๋๋ฉด์ ๋ชจ๋ ์์
์ด ๋๋ฌ์ ๋์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ํํ ์ ์์ต๋๋ค.
๐ก enter, leave, notoify๋ฅผ ์ด์ฉํด์ ์ฌ๋ฌ๊ฐ์ ๋น๋๊ธฐ ์์
๋ค์ด ์ ๋ถ ๋๋ ๋ ์์
์ ์ํํ๊ฒ ํ ์๋ ์์ต๋๋ค.
// https://stackoverflow.com/questions/49376157/swift-dispatchgroup-notify-before-task-finish
let group = DispatchGroup()
let queueImage = DispatchQueue(label: "com.image")
let queueVideo = DispatchQueue(label: "com.video")
group.enter()
queueImage.async(group: group) {
sleep(2)
print("image")
group.leave()
}
group.enter()
queueVideo.async(group: group) {
sleep(3)
print("video")
group.leave()
}
group.notify(queue: .main) {
print("all finished.")
}
51. DispatchWorkItem์ ์ฅ์ ์ด ๋ฌด์์ธ๊ฐ์? (What are the benefits of using DispatchWorkItem in Swift?)
๐ก DispatchWorkItem์ ์ฌ์ฉํ๋ฉด DispatchQueue์ ๋ฑ๋กํ ์์
์ ์บก์ํ
ํ ์ ์์ต๋๋ค.
let queue = DispatchQueue(label: "custom")
let workItem = DispatchWorkItem {
print("task is running")
}
queue.async(execute: workItem)
๐ก DispatchWorkItem์ ์ฌ์ฉํ๋ฉด cancel
, wait
๋ฑ ์ ๊ณต๋๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ์ฝ๊ฒ ์์
์ ๋ํ ๋์์ ์ง์ ํ ์ ์์ต๋๋ค.
class SearchViewController: UIViewController, UISearchBarDelegate {
// We keep track of the pending work item as a property
private var pendingRequestWorkItem: DispatchWorkItem?
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
// Cancel the currently pending item
pendingRequestWorkItem?.cancel()
// Wrap our request in a work item
let requestWorkItem = DispatchWorkItem { [weak self] in
self?.resultsLoader.loadResults(forQuery: searchText)
}
// Save the new work item and execute it after 250 ms
pendingRequestWorkItem = requestWorkItem
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250),
execute: requestWorkItem)
}
}
52. Concurrent์ Serial Queue๊ฐ async, sync์ ํจ๊ป ์ฌ์ฉ๋๋ ์ํฉ์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (Explain usage of Concurrent vs Serial Queues with async and sync blocks)
๐ก concurrent + sync
: DispatchQueue์ ์์
์ด sync
ํ๊ฒ ๋ฑ๋ก๋๊ธฐ ๋๋ฌธ์ ์์
์ ๋ฑ๋กํ๋ ์ค๋ ๋๋ ์์
์ ๋ฑ๋กํ๊ณ ์์
์ด ๋ง์ณ์ง ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค
. DispatchQueue์ ๋ฑ๋ก๋ ์์
์ concurrent
ํ๊ฒ ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ์์
์ ์ข
๋ฃ์ฌ๋ถ์ ์๊ด์์ด ํ ๋น ๊ฐ๋ฅํ ์ค๋ ๋๊ฐ ์๋ค๋ฉด ํ์ ์๋ ์์
์ ์ค๋ ๋์ ํ ๋น
์์ผ ์์
์ ์์ํฉ๋๋ค.
๐ก concurrent + async
: DispatchQueue์ ์์
์ด async
ํ๊ฒ ๋ฑ๋ก๋๊ธฐ ๋๋ฌธ์ ์์
์ ๋ฑ๋กํ๋ ์ค๋ ๋๋ ๋ฑ๋กํ ์์
์ด ๋๋๊ธธ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๊ณง๋ฐ๋ก ๋ค์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค. DispatchQueue์ ์๋ ์์
์ concurrent
ํ๊ฒ ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ์์
์ ์ข
๋ฃ์ฌ๋ถ์ ์๊ด์์ด ํ ๋น ๊ฐ๋ฅํ ์ค๋ ๋๊ฐ ์๋ค๋ฉด ํ์ ์๋ ์์
์ ์ค๋ ๋์ ํ ๋น
์์ผ ์์
์ ์์ํฉ๋๋ค.
๐ก serial + sync
: DispatchQueue์ ์์
์ด sync
ํ๊ฒ ๋ฑ๋ก๋๊ธฐ ๋๋ฌธ์ ์์
์ ๋ฑ๋กํ๋ ์ค๋ ๋๋ ์์
์ ๋ฑ๋กํ๊ณ ์์
์ด ๋ง์ณ์ง ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค
. DispatchQueue์ ๋ฑ๋ก๋ ์์
์ serial
ํ๊ฒ ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ํ์ฌ ์์
์ ๋ํ ์ฒ๋ฆฌ๊ฐ ๋๋๋ฉด
ํ์ ๋ฑ๋ก๋ ๋ค์ ์์
์ ์ค๋ ๋์ ํ ๋นํด ์์ํฉ๋๋ค.
๐ก serial + async
: DispatchQueue์ ์์
์ด async
ํ๊ฒ ๋ฑ๋ก๋๊ธฐ ๋๋ฌธ์ ์์
์ ๋ฑ๋กํ๋ ์ค๋ ๋๋ ๋ฑ๋กํ ์์
์ด ๋๋๊ธธ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๊ณง๋ฐ๋ก ๋ค์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค. DispatchQueue์ ๋ฑ๋ก๋ ์์
์ serial
ํ๊ฒ ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ํ์ฌ ์์
์ ๋ํ ์ฒ๋ฆฌ๊ฐ ๋๋๋ฉด
ํ์ ๋ฑ๋ก๋ ๋ค์ ์์
์ ์ค๋ ๋์ ํ ๋นํด ์์ํฉ๋๋ค.
53. @escaping์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก @escaping์ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋ ํด๋ก์ ๋ฅผ ํจ์๊ฐ ์ข ๋ฃ๋ ํ์ ์คํ๋ ์ ์๋๋ก ํ๋ ์์ฑ์ ๋๋ค.
func completionTest(completion: @escaping () -> Void) {
DispatchQueue.global().async {
completion()
}
print("1")
}
completionTest {
print("end")
}
// 1
// end
54. @objc์ dynamic์ ์ฐจ์ด์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. (What's the difference between marking a method as @objc vs dynamic, when would you do one vs the other?)
๐ก dynamic์ ํตํด ์ ์ธ๋ ๋ฉค๋ฒ๋ณ์๋ ๊ฐ์ฒด๋ Objective-C๋ฅผ ์ฌ์ฉํด์ ๋์ ์ผ๋ก ๋์คํจ์น
๋ฉ๋๋ค. ๋์ ๋์คํจ์น๋ ๋ฐํ์์ ํด๋์ค๊ฐ ์ฐ๊ด ํด๋์ค๋ค์ ๋ฉ์๋ ๊ตฌํ์ฒด๋ค ์ค ์ด๋ค ํด๋์ค์ ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ์ง ๊ฒฐ์ ํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๐ก @objc๋ ์ค์ํํธ์ API๋ฅผ Objective-C์์
์ฌ์ฉํ ์ ์๋๋ก ํ๋ ์์ฑ์ด๋๋ค.
55. Extension์ ๋ฉ์๋๋ฅผ Override ํ ์ ์์๊น์?
๐ก Extension์์๋ ๋ฉ์๋๋ฅผ override ํ ์ ์์ต๋๋ค
.
๐ก Extension์ ์๋ก์ด ํจ์
๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ด์ง ๊ธฐ์กด ํจ์๋ฅผ ๋์ฒดํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ ์๋๋๋ค.
56. RunLoop์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก RunLoop๋ ์ค๋ ๋ ๋น ํ๋์ฉ ์์ฑ๋์ด์ Thread์ ์์
์ด ์๊ธฐ๋ฉด ์ฒ๋ฆฌํ๊ณ , ์๋ ๋๋ ๋๊ธฐ์ํค๋ ์ญํ ์ ํฉ๋๋ค.
๐ก RunLoop๋ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ ์ธ
ํ ์ค๋ ๋์์๋ ์๋์ผ๋ก ์คํ๋์ง ์๊ณ ๊ฐ๋ฐ์๊ฐ ์ง์
์คํ์์ผ์ฃผ์ด์ผ ํฉ๋๋ค.
๐ก RunLoop๋ฅผ ์คํํ๋ฉด ์คํ๋๋ ๋์ ๋์ฐฉํ EventSource
(input source, timer source)๋ฅผ ์คํํฉ๋๋ค.
๐ก RunLoop๋ ํ ๋ฒ๋ง
์คํ๋๊ณ ์คํ์ด ๋๋๋ฉด ๋๊ธฐ์ํ๋ก ๋์๊ฐ๋๋ค.
57. autoreleasepool์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก autorelease๋ ์ฐธ์กฐ ์นด์ดํธ์ ๊ฐ์๋ฅผ ์ฆ์ํ์ง ์๊ณ ์์ฝ
์ ํ ์ ์๊ฒํ๋ ํค์๋์
๋๋ค. ์์ฝ๋ release๋ autoreleasepool์ ๋ฑ๋ก๋๊ณ , autoreleasepool ์ธ์คํด์ค๊ฐ ํด์ ๋๋ฉด
๋ฑ๋ก๋์ด ์๋ ์์ฝ๋ release๋ค์ด ๋ชจ๋ ์คํ๋ฉ๋๋ค.
๐ก ๋ง์ฝ ํจ์๊ฐ ๋๋๊ธฐ ์ ์ ๋ฉ๋ชจ๋ฆฌ์์ ํด์ ๋์ด์ผ ํ๋ ์ธ์คํด์ค๊ฐ ์๋ค๋ฉด autorelease pool๋ก ๋ช
์์ ์ผ๋ก ์ธ์คํด์ค์ ์ฐธ์กฐ ์นด์ดํธ๋ฅผ ์ค์ฌ์ค ์ ์์ต๋๋ค.
func useManyImages() {
let filename = pathForResourceInBundle
for _ in 0 ..< 5 {
for _ in 0 ..< 1000 {
let image = UIImage(contentsOfFile: filename) // 5000๊ฐ ์์ฑ
}
}
// 5000๊ฐ ํด์
}
func useManyImages() {
let filename = pathForResourceInBundle
for _ in 0 ..< 5 {
autoreleasepool {
for _ in 0 ..< 1000 {
let image = UIImage(contentsOfFile: filename) // 1000๊ฐ ์์ฑ
}
} // 1000๊ฐ ํด์
}
}
58. OperationQueue์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. DispatchQueue์๋ ์ด๋ค ๊ฒ์ด ๋ค๋ฅธ๊ฐ์?
๐ก OperationQueue
๋ ์์
์ ๋ํ๋ด๋ Operation ํด๋์ค์ ์คํ์ ๊ด๋ฆฌํ๋ ํ์
๋๋ค. GCD์๋ ๋ค๋ฅด๊ฒ OperationQueue๋ ๊ฐ์ฒดํ๋ ์์
์ ํ์์ ์ทจ์ํ ์ ์๊ณ , ํ์ ๋ฑ๋ก๋ ์ต๋ ์์
์ ๊ฐ์๋ฅผ ์ค์ ํ๊ฑฐ๋, ์์
๊ฐ์ ์์กด์ฑ
(์ด๋ค ์์
์ด ์ ํ๋์ด์ผ ํ๋์ง)์ ๋ํ ์ ๋ณด๋ ์ค์ ํ ์ ์์ต๋๋ค. ์ฆ, DispatchQueue๋ณด๋ค ์ข ๋ ๊ณ ์์ค์ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
๐ก OperationQueue๋ ๋ด๋ถ์ ์ผ๋ก DispatchQueue
๋ฅผ ์ด์ฉํฉ๋๋ค.
๐ก OperationQueue๋ ์์
์ ํ๋ฒ ๊ฐ์ฒดํ ํ๊ณ ๊ณ ์์ค API๋ฅผ ์ง์ํ๊ธฐ ๋๋ฌธ์ DispatchQueue๋ณด๋ค ๋ ๋ง์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉ
ํฉ๋๋ค. ๋ฐ๋ผ์ ๋ณต์กํ๊ณ ์์กด์ฑ์ ๋ํ ์ค์ ์ด ํ์ํ ์์
์ด ์๋๋ผ๋ฉด DispatchQueue๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ข์ ์๋ ์์ต๋๋ค.
59. final ํค์๋๋ฅผ ํด๋์ค ์์ ๋ถ์ด๋ฉด ์ด๋ค ํจ๊ณผ๊ฐ ์์๊น์?
๐ก ์ด๋ค ํด๋์ค์ ํ๋กํผํฐ๋ ๋ฉ์๋๋ ๋ค๋ฅธ ์์ ํด๋์ค๋ก๋ถํฐ override ๋ ์ ์๊ธฐ ๋๋ฌธ์, ์ด๋ฐ override๋ ๋ฉ์๋๋ ์ค์ ๋ก ์ด๋ค ๋ฉ์๋๋ฅผ ์คํํ ์ง vtable
์ ํ ๋ฒ ํ์ํด์ ๊ฒฐ์ ํ๊ฒ๋ฉ๋๋ค. ์ฆ, ์ปดํ์ผ ํ์์ด ์๋ ๋ฐํ์์ ์ค์ ๋ก ์คํํ ๋ฉ์๋๊ฐ ๊ฒฐ์
๋๋ ๊ฒ์
๋๋ค. ์ด๋ฅผ dynamic dispatch
๋ผ๊ณ ํฉ๋๋ค.
๐ก final ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋น ํด๋์ค, ํ๋กํผํฐ, ๋ฉ์๋๊ฐ ๋ค๋ฅธ ํด๋์ค์ ์ํด ์์๋๊ณ ์์ง ์๋ค๋ ๊ฒ์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ ค์ฃผ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ํ์์ ์ด๋ค ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ง ๋ฐ๋ก ๊ฒฐ์
ํ ์ ์๊ณ , vtable์ ๊ฑฐ์น์ง ์๊ณ ์ง์ ์ ์ผ๋ก ํธ์ถ๋๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ๋ ์ข์ ํผํฌ๋จผ์ค๋ฅผ ๋ผ ์ ์์ต๋๋ค.
60. vtable์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก vtable์ ๊ฐ์ ๋ฉ์๋ ํ
์ด๋ธ
๋ก ์ปดํ์ผ ํ์์ ์์ฑ
๋์ด ๋ฉ์๋๊ฐ ํธ์ถ๋์์ ๋ ์ฌ์ฉํ ๊ตฌํ์ฒด๋ฅผ ๋ฐํ์์ ํน์
ํ ์ ์๊ฒ ํด์ค๋๋ค.
๐ก vtable์ ๋ฉ์๋ ๊ตฌํ์ฒด์ ์ฃผ์๋ฅผ ๋ฐฐ์ด๋ก
๊ฐ์ง๊ณ ์์ต๋๋ค.
๐ก ํด๋์ค๋ง๋ค vtable
์ด ์กด์ฌํฉ๋๋ค.
-> ์์ง ์ ํํ ์ ๋ชจ๋ฅด๊ฒ ์ด์ https://developer.apple.com/videos/play/wwdc2016/416/ ์ด๊ฑฐ๋ถํฐ ๋ณด๋ ค๊ตฌ์ใ
61. ํ๋กํผํฐ ์ต์ ๋ฒ์ ๋ํด ์ค๋ช ํด๋ณด์ธ์.
๐ก ํ๋กํผํฐ ์ต์ ๋ฒ๋ ์ ์ฅ ํ๋กํผํฐ์ ๊ฐ์ด ๋ณํํ๋ ๊ฒ์ ๊ด์ฐฐ
ํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
๐ก willSet
๊ณผ didSet
์ ์ฌ์ฉํด์ ํ๋กํผํฐ์ ๊ฐ์ด ๋ณํํ ๋ ํจ๊ป ์คํํ ์์
์ ์ ์ํ ์ ์์ต๋๋ค.
๐ก willSet์ ์๋ก ๋ณํ๋ ๊ฐ์ newValue
๋ผ๋ ํ๋กํผํฐ๋ก ์ ๊ณตํ๊ณ , didSet์ ๋ณํ๋๊ธฐ ์ ๊ฐ์ oldValue
๋ผ๋ ํ๋กํผํฐ๋ก ์ ๊ณตํฉ๋๋ค.
class A {
var name: String {
willSet {
print("\(name) will be changed to \(newValue)")
}
didSet {
print("\(oldValue) is changed to \(name)")
}
}
init(name: String) {
self.name = name
}
}
let a = A(name: "A")
a.name = "B"
// A will be changed to B
// A is changed to B
๐ก ์ฐ์ฐํ๋กํผํฐ๋ ๋ถ๋ชจ ํด๋์ค์ ์ฐ์ฐ ํ๋กํผํฐ๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ๋ ๊ฒฝ์ฐ๋ง ํ๋กํผํฐ ์ต์ ๋ฒ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
61. Property Wrapper์ ๋ํด ์ค๋ช ํด๋ณด์ธ์.
๐ก ํ๋กํผํฐ ๋ํผ๋ ์ฌ๋ฌ ํ๋กํผํฐ์ ๋ํด ๋ฐ๋ณต๋๋ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉ
ํ ์ ์๋๋ก ํด์ฃผ๋ ๊ธฐ๋ฅ์
๋๋ค.
๐ก @propertyWrapper
๋ก ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ํ๊ณ ๋ด๋ถ์ ํ๋กํผํฐ์ ๋ํ ๋์์ ์ ์ํด๋๋ฉด, ํ๋กํผํฐ๋ฅผ ์ ์ธํ ๋ ํ๋กํผํฐ ๋ํผ๋ฅผ ํค์๋๋ก ๋ถ์ฌ ๋ฏธ๋ฆฌ ์ ์ํ ๋์์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
@propertyWrapper
struct TwelveOrLess {
private var number = 0
var wrappedValue: Int {
get { return number }
set { number = min(newValue, 12) }
}
}
struct SmallRectangle {
@TwelveOrLess var height: Int
@TwelveOrLess var width: Int
}
var rectangle = SmallRectangle()
print(rectangle.height)
// Prints "0"
rectangle.height = 10
print(rectangle.height)
// Prints "10"
rectangle.height = 24
print(rectangle.height)
// Prints "12"
62. ๊ณ ์ฐจํจ์ ์ค flatMap๊ณผ compactMap์ ์ฐจ์ด๋ฅผ ์ค๋ช ํด๋ณด์ธ์.
๐ก compactMap
์ 1์ฐจ์ ๋ฐฐ์ด์์ ๊ฐ ์์์ ๋ํด nil์ ์ ๊ฑฐ
ํ๊ณ ์ต์
๋ ๋ฐ์ธ๋ฉ
์ ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ง๋ค์ด ๋ฐํํฉ๋๋ค.
๐ก flatMap
์ ๋ฐฐ์ด์ ์์ ํ์
์ด ์ต์
๋์ด๋ผ๋ฉด, nil์ ์ ๊ฑฐ
ํ๊ณ ์ต์
๋ ๋ฐ์ธ๋ฉ
์ ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ง๋ค์ด ๋ฐํํฉ๋๋ค.
๐ก flatMap
์ 2์ฐจ์ ๋ฐฐ์ด์ด๋ฉด์ ์์ ํ์
์ด ์ต์
๋์ด ์๋๋ผ๋ฉด, ๋ฐฐ์ด์ ์์๋ค์ 1์ฐจ์์ผ๋ก ํฉ์น ๋ฐฐ์ด
์ ๋ฐํํ๊ณ nil์ ์ ๊ฑฐ์ ์ต์
๋ ๋ฐ์ธ๋ฉ์ ํ์ง ์์ต๋๋ค.
let test = [1, nil, 2, nil, 3, nil]
print(test.compactMap({ $0 }))
// [1, 2, 3]
let test = [1, nil, 2, nil, 3, nil]
print(test.flatMap({ $0 }))
// [1, 2, 3]
let test = [[1, nil], [2, nil], [3, nil]]
print(test.flatMap({ $0 }))
// [Optional(1), nil, Optional(2), nil, Optional(3), nil]
let test = [[1, nil], [2, nil], [3, nil]]
print(test.flatMap({ $0 }).compactMap({ $0 }))
// [1, 2, 3]
let test = [[1, nil], [2, nil], [3, nil]]
print(test.compactMap({ $0 }).flatMap({ $0 }))
// [Optional(1), nil, Optional(2), nil, Optional(3), nil]
let test = [[1, nil], [2, nil], [3, nil], nil]
print(test.compactMap({ $0 }).flatMap({ $0 }))
// [[Optional(1), nil], [Optional(2), nil], [Optional(3), nil]]
63. High Order Function์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก ๊ณ ์ฐจํจ์๋ ํจ์๋ฅผ ์ธ์๋ก ๋ฐ๊ฑฐ๋ ํจ์๋ฅผ ๊ฒฐ๊ณผ๋ก ๋ฐํํ ์ ์๋ ํจ์์ ๋๋ค.
func test(execution: () -> Void) {
execution()
}
64. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ฌด์์ธ๊ฐ์? Swift๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ธ๊ฐ์?
๐ก ํจ์ํ ํ๋ก๊ทธ๋จ๋ฐ์ ์์ ํจ์
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์์
๋๋ค. ์์ ํจ์๋ ์ด๋ค ์
๋ ฅ์ ๋ํด ํญ์ ๊ฐ์ ์ถ๋ ฅ
์ ๋ง๋๋ ํจ์๋ฅผ ์๋ฏธํฉ๋๋ค. ์ฆ, ์ธ๋ถ์ ์ํฅ์ ์ฃผ๊ฑฐ๋ ๋ฐ๋ side effect
๊ฐ ์์ต๋๋ค.
๐ก ์ค์ํํธ๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ด๋ฉด์ ๋์์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋จ๋ฐ ์ธ์ด์ ํน์ง์ธ ์์, ์๋, ์บก์ํ, ์ถ์ํ ๋ฑ์ ์ ๊ณตํ๋ ๋ฉํฐ ํจํฐ๋ค์ ์ธ์ด์
๋๋ค.
65. ์์ํจ์๊ฐ ๋ฌด์์ธ๊ฐ์?
๐ก ์์ํจ์๋ ๋์ผํ ์
๋ ฅ์ ๋ํด ํญ์ ๋์ผํ ์ถ๋ ฅ
์ ๊ฐ์ง๋ ํจ์์
๋๋ค.
๐ก ์์ํจ์๋ ์ฌ์ด๋ ์ดํํธ
๋ฅผ ๊ฐ์ง๋ฉด ์๋ฉ๋๋ค.
66. ๊ทธ๋ผ ์ฌ์ด๋ ์ดํํธ๋ ๋ฌด์์ธ๊ฐ์?
๐ก ์ฌ์ด๋ ์ดํํธ๋ ํจ์๋ฅผ ํตํด ํจ์ ์ธ๋ถ ๊ฐ์ ์ํ๊ฐ ๋ณํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
var name = “hunihun956”
func getName() -> String { // input(()) -> output(String from outer scope) | Side Effect
return name
}
func getName(name: String) -> String { // input(String) -> output(String) | No Side Effect
return name
}
67. ์์ ํจ์๊ฐ ์ ํ์ํ๋ค๊ณ ์๊ฐํ๋์?
๐ก ๊ฐ์ ์
๋ ฅ์ ๋ํด ํญ์ ๊ฐ์ ์ถ๋ ฅ์ ๋ง์กฑํ๋ ์์ํจ์๋ ํ
์คํธ๊ฐ ์ฉ์ด
ํฉ๋๋ค. ์ธ๋ถ ์ํ์ ์ํฅ์ ๋ฐ์ง ์๊ธฐ ๋๋ฌธ์ ํด๋น ํจ์๋ง ํ
์คํธํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๐ก ์ฌ์ดํธ ์ดํํธ๊ฐ ์๋ค๋ ๊ฒ์ ์์ ํจ์๋ค์ ํฌํจํ๋ ๊ฐ์ฒด์ ์ ์ง๋ณด์์ฑ
์ด ์ข๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ํ๋กํผํฐ๋ ํจ์๋ค์ด ๋ค๋ฅธ ํจ์๋ค์ ์์กด์ ์ด์ง ์๊ธฐ ๋๋ฌธ์ ํ์ฅ๊ณผ ๋ณ๊ฒฝ์ด ์ฝ๊ฒ ๊ฐ๋ฅํฉ๋๋ค.
68. 1๊ธ ๊ฐ์ฒด(ํน์ 1๊ธ ์๋ฏผ)์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์. Swift์๋ ์ด๋ค 1๊ธ ๊ฐ์ฒด๋ค์ด ์๋์?
๐ก 1๊ธ ๊ฐ์ฒด๋ ํจ์์ ์ธ์๋ก ์ ๋ฌ๋๊ฑฐ๋ ๋ฐํ ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๋
๊ฐ์ฒด๋ฅผ ์๋ฏธํฉ๋๋ค.
๐ก ๋ 1๊ธ ๊ฐ์ฒด๋๋ณ์๋ ์์์ ํ ๋น
ํ ์ ์๋ ๊ฐ์ฒด์
๋๋ค.
๐ก ์ค์ํํธ๋ ๊ธฐ๋ณธ ํ์
๋ค๊ณผ ํจ์๋ ํด๋ก์ ๊น์ง ๋ชจ๋ 1๊ธ ๊ฐ์ฒด์ ํด๋นํฉ๋๋ค.
69. Optional์ ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ๊ตฌํ๋์ด ์๋์?
๐ก Optional์ associated value๋ฅผ ๊ฐ์ง๋ enum
์ผ๋ก ๊ตฌํ๋์ด ์์ต๋๋ค. ๊ฐ์ด ์กด์ฌํ ๋๋ some์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ๊ณ , ๊ฐ์ด ์กด์ฌํ์ง ์์ผ๋ฉด nil์ ๋ฐํํฉ๋๋ค.
@frozen
enum Optional<Wrapped> {
case none
case some(Wrapped)
}
70. Swift์์ ์ฐธ์กฐ ํ์ ์ ๋งํด๋ณด์ธ์.
๐ก ํด๋์ค, ํจ์, ํด๋ก์ ๊ฐ ๋ชจ๋ ์ฐธ์กฐ ํ์ ์ ๋๋ค.
71. String์ ์ subscript๋ก ์ ๊ทผํ ์ ์์๊น์?
๐ก String์ ๊ตฌ์ฑํ๋ ๊ฐ ๋ฌธ์๋ค์ ์ฌ๋ฌ๋ฌธ์๊ฐ ํฉ์ฑ๋ Unicode Scalar
๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค. ๋ฐ๋ผ์ ํ ๋ฌธ์๊ฐ ๊ฐ์ ํฌ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ์ง์ง ์์ต๋๋ค.
// https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-ID285
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ฬ
// eAcute is é, combinedEAcute is é
72. Result ํ์ ์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก Result๋ success์ failure case
๋ฅผ ๊ฐ์ง๋ enum์
๋๋ค.
๐ก failure ์ผ์ด์ค์ associated value๋ ๋ฐ๋์ Error ํ๋กํ ์ฝ
์ ์ฑํํด์ผํฉ๋๋ค.
๐ก ๋คํธ์ํฌ์ ๊ฐ์ด ์คํจํ ๊ฐ๋ฅ์ฑ์ด ์๋ ์์
์ ์ฑ๊ณต์ฌ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ์ฝ๊ฒ ํํํ ์ ์์ต๋๋ค.
// https://www.hackingwithswift.com/articles/161/how-to-use-result-in-swift
fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in
switch result {
case .success(let count):
print("\(count) unread messages.")
case .failure(let error):
print(error.localizedDescription)
}
}
73. some ํค์๋์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก some์ opqaue result type
์
๋๋ค.
๐ก ํจ์ ๋ด๋ถ์์ ๋ฐํ๋๋ ํ์
์ ์ธ๋ถ์์ ๋ช
ํํ๊ฒ ์ ์ ์๋๋กํฉ๋๋ค.
// Error. ๊ตฌ์ฒดํ์
์ ๋ช
์ํ์ง ์์
func someList() -> Collection {
return [1,2,3]
}
// OK. ๊ตฌ์ฒดํ์
์ ์ ์๋ ์์ง๋ง Collection์ ์ฑํํ๋ ํ์
์ด ๋ฐํ๋ ๊ฒ์ ๋ณด์ฆํจ
func someList() -> some Collection {
return [1,2,3]
}
74. KVC์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก KVC๋ Key-Value Coding
์ผ๋ก ๊ฐ์ฒด์ ๊ฐ์ ์ง์ ์ฌ์ฉํ์ง ์๊ณ KeyPath๋ฅผ ์ด์ฉํด ๊ฐ์ ์
์ผ๋ก ์ฌ์ฉํ๊ณ ์์ ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
๐ก {๋ฐฑ์ฌ๋์(\)}.{ํ์
}.{keypath}
๋ก keypath๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
struct A {
var data = "Data"
}
var aInstance = A()
print(aInstance[keyPath: \.data]) // Data
print(aInstance.data) // Data
aInstance[keyPath: \.data] = "Data2"
print(aInstance[keyPath: \.data]) // Data2
let key = \A.data
print(aInstance[keyPath: key]) // Data2
75. KVO์ ๋ํด์ ์ค๋ช ํด๋ณด์ธ์.
๐ก KVO๋ Key-Value Oberving
์ผ๋ก ์ด๋ค Key์ ๋ฑ๋ก๋ ๋ณ์๊ฐ ๋ณ๊ฒฝ์ด ๋๋ ๊ฒ์ ๊ด์ฐฐํ๊ณ ๋ณ๊ฒฝ์ด ๋ฐ์ํ ๋๋ง๋ค ํน์ ํ ์์
์ ์ํํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.
๐ก Objective-C ๋ฐํ์์ ์์กดํ๊ธฐ ๋๋ฌธ์ NSObject
๋ฅผ ์ฑํํด์ผํ๊ณ , ๊ด์ฐฐํ ํ๋กํผํฐ์๋ @objc
์ dynamic
ํค์๋๋ฅผ ๋ถ์ฌ์ผ ํฉ๋๋ค.
class Obj: NSObject {
@objc dynamic var data = "Data"
}
let obj = Obj()
let observer = obj.observe(\.data, options: [.new, .old]) { _, changeInfo in
print("\(changeInfo.oldValue) has been changed to \(changeInfo.newValue)")
}
obj.data = "Data2"
// Optional("Data") has been changed to Optional("Data2")
Questions Source
๐ก https://www.fullstack.cafe/interview-questions/swift
๐ก https://github.com/JeaSungLEE/iOSInterviewquestions
'๐ ์์ด-์ค-์์ค > ๐ค ์ค์ํํธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] Method Dispatch (2): ๋ ๋ณต์กํ ์ํฉ์ Method Dispatch (0) | 2021.12.26 |
---|---|
[Swift] Method Dispatch (1): Static Dispatch vs. Dynamic Dispatch (1) | 2021.12.26 |
[Swift] GCD(Grand Central Dispatch) - Dispatch Queue (2) | 2021.10.25 |
[Swift] ์ค์ํํธ์ ๊ณ ์ฐจํจ์๋ค(High Order Functions) (0) | 2021.10.10 |
[Swift] Swift์ ์ฐ์ฒด๊ตญ, NotificationCenter (0) | 2021.09.19 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote