<h1><center> iOS interview 7 </center></h1>
###### tags: `๐ป ๋ฉด์ ์ง๋ฌธ`
###### date: `2025-10-1217:21:33.284Z`
> [iOS interview](https://github.com/JeaSungLEE/iOSInterviewquestions)
## ๋ชฉํ
๋ง์ ๋ง์ด ์ฐ์ตํ์!
- concurrency ๋ง๋ฌด๋ฆฌ
- ๋ฉด์ ์ง๋ฌธ๋ฆฌ์คํธ ๋๋จธ์ง
## Level2
### ์์ง
10. UIKit์์ ํ
์ด๋ธ ๋ทฐ(UITableView)์ ์ปฌ๋ ์
๋ทฐ(UICollectionView)์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ์?
- ํ
์ด๋ธ ๋ทฐ์ ์ปฌ๋ ์
๋ทฐ์์ ์
์ ์ฌ์ฌ์ฉํ๋ ์ด์ ์ ๋ฐฉ๋ฒ์ ์ค๋ช
ํด์ฃผ์ธ์.
- ํ
์ด๋ธ ๋ทฐ์ ์ปฌ๋ ์
๋ทฐ์ ๋ฐ์ดํฐ ์์ค(Data Source)์ ๋ธ๋ฆฌ๊ฒ์ดํธ(Delegate)์ ์ญํ ์ ๋ฌด์์ธ๊ฐ์?
- ์ปฌ๋ ์
๋ทฐ์์ ์ฌ์ฉํ ์ ์๋ ๋ ์ด์์(Layout)์ ์ข
๋ฅ์ ํน์ง์ ์ค๋ช
ํด์ฃผ์ธ์.
> UIKit ์ ๋ชจ๋ฅด๋ ์ฌ๋์ด๋ผ.. ์ง์ง ์ด ์ฐจ์ด๊ฐ ๋ญ์ง ๊ถ๊ธํด์ ๊ฐ์ ธ์์ด์
ํ
์ด๋ธ ๋ทฐ๋ ๋จ์ผ ์ด / ์ปฌ๋ ์
๋ทฐ๋ ๋ณต์กํ UI ํ์ฉ ๊ฐ๋ฅ
-> ์ฌ์ค ์ปฌ๋ ์
๋ทฐ๋ก ๋ค ๊ฐ๋ฅ
๋จ์ํ ๋ฆฌ์คํธ์ธ ๊ฒฝ์ฐ, ํ
์ด๋ธ ๋ทฐ๊ฐ ๋ ์ข์
ํ
์ด๋ธ ๋ทฐ๋ Swipable ์ ์ฉ ๊ฐ๋ฅ
์ปฌ๋ ์
๋ทฐ๋ ์ ์ฉ ๋ถ๊ฐ๋ฅ
FlowLayout / CompositionalLayout
- FlowLayout
- ์ง์ ๊ณ์ฐ ํ์
- ๋๋ฌด ์ค๋๋จ
- CompositionalLayout
- ๋น์จ๋ก Section, Group, Item ์ ์ฉ ๊ฐ๋ฅ
- ์ด๊ฑธ ๋ ๋ง์ด ์ฐ๊ฑฐ๋ผ
11. ๋ ๊ฑฐ์ MVC ํ๋ก์ ํธ๋ฅผ MVVM์ผ๋ก ์ ์ง์ ์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ๋ ค๋ฉด ์ด๋ค ์ ๋ต์ ์ฌ์ฉํ์๊ฒ ์ต๋๊น?
๐ก ํํธ: ๋ฆฌ์คํฌ๋ฅผ ์ต์ํํ๋ฉด์ ์ ์ง์ ์ผ๋ก ์ ํํ๋ ๋ฐฉ๋ฒ์ ์๊ฐํ์ธ์
- ์ด๋ค ํ๋ฉด๋ถํฐ ๋ง์ด๊ทธ๋ ์ด์
์ ์์ํ๋ ๊ฒ์ด ์ข์๊น์?
- ๋ณต์ก๋๊ฐ ๋์ ํ๋ฉด vs ๋จ์ํ ํ๋ฉด, ์ด๋ค ๊ธฐ์ค์ผ๋ก ์ ํํ๋์?
> ๋ณต์ก๋๊ฐ ๋์ผ๋ฉด ๋ ๋ค์ ์งํํ๋ค
> ํ
์คํธ๋ฅผ ๋ ๋ง์ด ์์ฑํด๋ด์ผํ๋ค / ์ฌ์ฉ์ฑ ํ
์คํธ๋ ๋ง์ด ํด๋ด๋ผ
- ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง๊ฐ ๋์ ๋ถ๋ถ๋ถํฐ ์์ํ๋ ์ด์ ๋?
> ์ ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๊ณ ๋ คํด์ผ ํ์ง?
- MVC์ MVVM์ด ๊ณต์กดํ๋ ๊ณผ๋๊ธฐ์ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ ํด๊ฒฐ์ฑ
์?
- ๋ฐ์ดํฐ ํ๋ฆ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๋ฐฉ๋ฒ์?
- ํ์๋ค์ ํผ๋์ ์ต์ํํ๋ ๋ฐฉ๋ฒ์?
- ์ํคํ
์ฒ ๋ณ๊ฒฝ์ ์ฑ๊ณต ์งํ๋ ๋ฌด์์ผ๋ก ์ธก์ ํ๋์?
> Presentation layer์ ์ํคํ
์ฒ ๋ณ๊ฒฝ ์, ํ
์คํธ ์งํ ๋ฐฉ๋ฒ์ด ์ด๋ป๊ฒ ๋๋์ง?
> ๋ง์ด๊ทธ๋ ์ด์
์งํ ์, ๊ธฐ์กด ํ์ฉ ๊ฐ์ฒด์ ๋๊ฐ๋ค๋ฉด ๋ค์ด๋ฐ ์ฐจ์ด๋ฅผ ์ด๋ป๊ฒ ๋๋์ง?
14. ์ฌ๋ฌ ๊ฐ์ ๋น์ทํ ๋คํธ์ํฌ API ํด๋ผ์ด์ธํธ๋ฅผ ํ๋กํ ์ฝ๋ก ์ถ์ํํ๋ ค๋ฉด ์ด๋ป๊ฒ ์ค๊ณํ์๊ฒ ์ต๋๊น?
- ๊ณตํต ๊ธฐ๋ฅ์ ํ๋กํ ์ฝ ํ์ฅ์ผ๋ก ๊ตฌํํ ๋์ ์ด์ ๊ณผ ์ฃผ์์ ์?
- ํ๋กํ ์ฝ ํ์ฅ์ ๋ฉ์๋ ๋์คํจ์น ๋ฐฉ์๊ณผ override ๋ถ๊ฐ๋ฅํ ์ด์ ๋?
- Associated Type์ ์ฌ์ฉํ ์ ๋ค๋ฆญ ํ๋กํ ์ฝ์ ์ฅ๋จ์ ์?
- ํ
์คํธ๋ฅผ ์ํ Mock ๊ฐ์ฒด ์์ฑ์ด ์ฌ์ด ํ๋กํ ์ฝ ์ค๊ณ ๋ฐฉ๋ฒ์? <- ์ง์ง ๊ถ๊ธํ๊ฑด ์ด๊ฑฐ ๐ก
> ์์ง ์๊ฐ..
> ์์กด์ฑ ์ฃผ์
์ด ๊ฐ๋ฅํ ํํ๋ก ์ค๊ณํด์ผ ํ๋ค?
> ํ์ํ ๋ค๋ฅธ ๊ฐ์ฒด๋ค์ ๋ํด์๋ Mock์ผ๋ก ์ฃผ์
ํ ์ ์์ด์ผ ํจ..?
- Dependency Injection๊ณผ ํ๋กํ ์ฝ์ ๊ด๊ณ๋?
- SwiftUI์ View ํ๋กํ ์ฝ์ฒ๋ผ PAT(Protocol with Associated Type)๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์?
-
TCA ์ฐ์ธ์.. TestFeature ์ง์
### ํํ
1. ํ
์ด๋ธ๋ทฐ๋ฅผ ๋น ๋ฅด๊ฒ ์คํฌ๋กคํ ๋ ์ด๋ฏธ์ง๊ฐ ์๋ชป๋ ์
์ ํ์๋๋ ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์?
- ์
์ฌ์ฌ์ฉ ๋ฉ์ปค๋์ฆ
> Cell์ด queue(ํ)์์ ๋ค์ reuse(์ฌ์ฌ์ฉ)๊ฐ ๋ ๋ prepareForReuse()๋ฅผ ๊ฑธ์ณ์ ์ด๊ธฐํ๋ฅผ ํ ํ ๋ค์ cellForeRowAt๋ฅผ ํตํด Cell์ด ํ์๊ฐ ๋ฉ๋๋ค.
- ์
์ฌ์ฌ์ฉ(Cell Reuse) ๋ฉ์ปค๋์ฆ์ด ์ด ๋ฌธ์ ์ ์ด๋ค ๊ด๋ จ์ด ์๋์?
> SwiftUI์์ ๊ธฐ๋ณธ VStack/HStack์์๋ ์ฌ์ฌ์ฉ ๊ณ ๋ ค X..
> List๋ LazyVStack, LazyHStack ๊ฐ์ ์น๊ตฌ๋ค์ ๋ด๋ถ์ ์ผ๋ก ์์์ ์ฌ์ฌ์ฉํด์ค๋๋ค์ ๋ค๋น
~~5. viewDidLoad์์ ๋คํธ์ํฌ ์์ฒญ์ ํ๋ฉด ์ด๋ค ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋์?~~
8. iOS ์ฑ์์ ์์กด์ฑ ์ฃผ์
(Dependency Injection)์ ์ด๋ค ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋์?
- ์ถ์ํ
- ํ์ฅ์ฑ
- ๋ง์ด๋ค ์ด์ผ๊ธฐํ๋ DI ๊ฐ ๊ฐ์ง๋ ์ฅ์ ์ด๋ ๋ชฉ์ ์ผ๋ก๋, ํ
์คํธ ์ฉ์ด / ์ ์ง๋ณด์ ์ฉ์ด / ๊ฒฐํฉ ๋ฎ์ถ๊ธฐ ๋ฑ?
- ๊ทผ๋ฐ ์ง์ง ์จ๋ณด๊ณ ๋๋ ๊ฐ์ฅ ํฐ ์ฅ์ ์
- ๋ด๋ถ ๊ตฌํ ์์ด ํ์ฉ์ด ๊ฐ๋ฅํด์ ธ์ ๊ตฌํ ์๋๋ ํธ์๊ฐ ์ข๋ค?
17. Swift์ ๊ณ ๊ธ ์ ๋ค๋ฆญ ๊ธฐ๋ฅ๊ณผ ํ์
์๊ฑฐ(Type Erasure)์ ๋ํด ์ค๋ช
ํด์ฃผ์ธ์.
- AnyPublisher
18. iOS ์ฑ์์ Deep Link์ Universal Link์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ์?
applinks:app.com
### ํ์ค
8. iOS ์ฑ์์ ์์กด์ฑ ์ฃผ์
(Dependency Injection)์ ์ด๋ค ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋์?
- ์์กด์ฑ ์ฃผ์
์ ์ธ ๊ฐ์ง ์ ํ(Initializer Injection, Property Injection, Method Injection)์ ์ค๋ช
ํด์ฃผ์ธ์.
init(),
```swift
let vc = UserViewController()
vc.viewModel = UserViewModel(client: RealAPIClient())
```
> Property Injection
```swift
final class UserService {
func fetchUser(using client: APIClient) async throws -> User { // โ
๋ฉ์๋ ์ฃผ์
try await client.request(.getUser)
}
}
```
> Method Injection
- ์์กด์ฑ ์ฃผ์
์ปจํ
์ด๋(Dependency Injection Container)๋ ๋ฌด์์ธ๊ฐ์?
ํฉํ ๋ฆฌ ๊ฐ์ ๋
14. ์ฌ๋ฌ ๊ฐ์ ๋น์ทํ ๋คํธ์ํฌ API ํด๋ผ์ด์ธํธ๋ฅผ ํ๋กํ ์ฝ๋ก ์ถ์ํํ๋ ค๋ฉด ์ด๋ป๊ฒ ์ค๊ณํ์๊ฒ ์ต๋๊น?
- ๊ณตํต ๊ธฐ๋ฅ์ ํ๋กํ ์ฝ ํ์ฅ์ผ๋ก ๊ตฌํํ ๋์ ์ฃผ์์ ์?
๊ด๋ฆฌํ ๊ณณ์ด ๋ง์์ง๋ค.
Pureํ ๊ณณ์์๋ง ์ฐ๊ธฐ
- ํ๋กํ ์ฝ ํ์ฅ์ ๋ฉ์๋ ๋์คํจ์น ๋ฐฉ์๊ณผ override ๋ถ๊ฐ๋ฅํ ์ด์ ๋?
override - ๊ตฌํ์ฒด๊ฐ ์๋๋ฏ๋ก ๋ถ๊ฐ๋ฅํจ
```
๊ตฌ๋ถ ์ ์ ์์น ๋์คํจ์น ๋ฐฉ์ ์ค๋ช
โ ํ๋กํ ์ฝ ์๊ตฌ์ฌํญ protocol ๋ณธ๋ฌธ ๋์ ๋์คํจ์น ์ค์ ํ์
์ด ์ด๋ค ๊ตฌํ์ ๊ฐ์ง๊ณ ์๋์ง ๋ฐํ์์ ๊ฒฐ์
โก ํ๋กํ ์ฝ ํ์ฅ ๋ฉ์๋ extension ๋ด๋ถ (์๊ตฌ์ฌํญ ์๋) ์ ์ ๋์คํจ์น ์ปดํ์ผ ํ์์ ๊ฒฐ์ (์ค๋ฒ๋ผ์ด๋ ๋ถ๊ฐ)
```
- Associated Type์ ์ฌ์ฉํ ์ ๋ค๋ฆญ ํ๋กํ ์ฝ์ ์ฅ๋จ์ ์?
```swift
protocol DataSource {
associatedtype Item
func item(at index: Int) -> Item
}
struct IntSource: DataSource { func item(at index: Int) -> Int { 1 } }
struct StringSource: DataSource { func item(at index: Int) -> String { "A" } }
let sources: [Any] = [IntSource(), StringSource()]
for source in sources {
if let intSource = source as? IntSource {
print(type(of: intSource.item(at: 0))) // Int (๋ฐํ์์ ํ์ธ)
} else if let strSource = source as? StringSource {
print(type(of: strSource.item(at: 0))) // String
}
}
```
> ๋ฐํ์์๋ง ์ ์ ์๋ ์ํฉ
20. Swift์์ ํค ๊ฒฝ๋ก(Key Path)๋ ๋ฌด์์ด๋ฉฐ, ์ด๋ป๊ฒ ์ฌ์ฉํ๋์?
> (\.model)
- ๋ฐํ์์ ํค ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ธ๊ฐ์?
์ธ์คํด์ค์์ ์ง์ ์ ๊ทผํ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋ฉด, ์์ฑ ์ด๋ฆ์ด ์ฝ๋์ ํ๋์ฝ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ ๊ทผํ ์์ฑ์ด ์ปดํ์ผ ํ์์ ๊ณ ์ ๋๋ค.
Key Path๋ก ์ ๊ทผํ๋ค๋ฉด?
์ ๊ทผํ ์์ฑ์ ๋ฐํ์์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
(์ฌ์ค ์ด ๋ง์ด ๋๋ฌด ์๋ฟ์ง ์์ง๋ง.. ์๋์ ๊ฐ์ ์์๋ฅผ ๋ค ์ ์์ ๋ฏ)
```swift
func getValue<T>(from book: Book, keyPath: KeyPath<Person, T>) -> T {
return book[keyPath: keyPath]
}
let title = getValue(from: book, keyPath: \Book.title) // "์๋
"
let price = getValue(from: book, keyPath: \Book.price) // 10000
struct User {
var name: String
var age: Int
}
var user = User(name: "TaeYoon", age: 26)
let writablePaths: [String: WritableKeyPath<User, Any>] = [
"name": \User.name as! WritableKeyPath<User, Any>,
"age": \User.age as! WritableKeyPath<User, Any>
]
// โ ๏ธ ์ฃผ์: ํ์
์บ์คํ
์ด ํ์ (KeyPath๋ ์ ๋ค๋ฆญ ํ์
์์ ๊ตฌ์กฐ)
if let keyPath = writablePaths["age"] {
user[keyPath: keyPath] = 27
}
print(user.age) // 27
```
> ์ค์ ๊ฐ ํ ๋น ๋ฐ ๊ฐ์ ธ์ค๋๊ฑด ๋ฐํ์
- ํค ๊ฒฝ๋ก์ KVO(Key-Value Observing)์ ๊ด๊ณ๋ฅผ ์ค๋ช
ํด์ฃผ์ธ์.
```swift
import Foundation
class Person: NSObject {
@objc dynamic var name: String
init(name: String) {
self.name = name
}
}
class ViewController: UIViewController {
var person: Person!
var observation: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
person = Person(name: "Alice")
// โฌ๏ธ ์ฌ๊ธฐ ์ด๋ ๊ฒ KeyPath๋ก ์ ๊ทผํ๋ค
observation = person.observe(\.name, options: [.new]) { (person, change) in
if let newName = change.newValue {
print("Name changed to: \(newName)")
}
}
}
deinit {
observation?.invalidate()
}
}
```
https://ahyeonlog.tistory.com/38