reduce 고차함수는 단순히 배열같은 컬렉션을 하나의 연산을 하여 결과값을 나타내는 용도로만 사용할 수 있다고 생각했다.
하지만 reduce 함수 내에 조건을 부여하여 단순한 사칙연산뿐만 아니라 원하는대로 마치 filter를 사용하는 것처럼 활용할 수 있다는 점을 알았다.
UIKit MainStoryboard File Base Name 항목 삭제SceneDelegate에 초기 화면 설정func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowSceene) else { return }
let window = UIWindow(windowScene: windowScene)
window.rootViewController = ViewController() // 기본 VC 설정
window.makeKeyAndVisible() // 활성화
self.window = window
}
import UIKit
import SnapKit
class ViewController: UIViewController {
private var num: Int = 0
var countLabel = UILabel()
var minusButton = UIButton()
var plusButton = UIButton()
var resetButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
setUI()
setButtonAction()
}
func setUI() {
setLabel()
setButton()
[countLabel, minusButton, plusButton, resetButton].forEach {
view.addSubview($0)
}
countLabel.snp.makeConstraints {
$0.width.equalTo(80)
$0.center.equalToSuperview()
}
[minusButton, plusButton].forEach { (btn: UIButton) in
btn.snp.makeConstraints {
$0.width.equalTo(80)
$0.height.equalTo(30)
$0.centerY.equalTo(countLabel)
}
}
minusButton.snp.makeConstraints {
$0.trailing.equalTo(countLabel.snp.leading).offset(-32)
}
plusButton.snp.makeConstraints {
$0.leading.equalTo(countLabel.snp.trailing).offset(32)
}
resetButton.snp.makeConstraints {
$0.width.equalTo(80)
$0.height.equalTo(30)
$0.centerX.equalToSuperview()
$0.top.equalTo(countLabel.snp.bottom).offset(32)
}
}
func setLabel() {
countLabel.text = "\(num)"
countLabel.textColor = .white
countLabel.font = .systemFont(ofSize: 45, weight: .bold)
countLabel.textAlignment = .center
}
func setButton() {
minusButton.setTitle("-", for: .normal)
minusButton.backgroundColor = .red
plusButton.setTitle("+", for: .normal)
plusButton.backgroundColor = .blue
resetButton.setTitle("초기화", for: .normal)
resetButton.backgroundColor = .gray
[minusButton, plusButton, resetButton].forEach {
$0.titleLabel?.textColor = .white
$0.layer.cornerRadius = 8
$0.clipsToBounds = true
}
}
func setButtonAction() {
let minusNum = UIAction { [weak self] _ in
self?.num -= 1
self?.updateLabel()
}
let addNum = UIAction { [weak self] _ in
self?.num += 1
self?.updateLabel()
}
let reset = UIAction { [weak self] _ in
self?.num = 0
self?.updateLabel()
}
minusButton.addAction(minusNum, for: .touchUpInside)
plusButton.addAction(addNum, for: .touchUpInside)
resetButton.addAction(reset, for: .touchUpInside)
}
func updateLabel() {
countLabel.text = "\(num)"
}
}
→ SnapKit을 처음 활용해보았는데, offset 개념이 아직 익숙하지 않다.
사용하다보면 점차 익숙해지리라 믿는다!
그 부분 말고는 예전보다 작성해야할 코드가 줄어들어 유용한 것 같다.
야구게임 과제에서 게임 기록을 관리하는 RecordManager의 addRound() 함수에 버그가 있었다.
기존 코드
func addRound() {
record.round = record.attempts.isEmpty ? record.round : +1
record.attempts.append(0)
}
삼항 연산자에서 false 부분에 +1로 표기하였는데, +=1의 동작을 생각하고 저렇게 작성하였으나 다시 보니 record.round = 1과 동일하였다.
그래서 3번째 게임부터는 정상적으로 기록이 되지 않고 2번째 기록에 시도횟수가 더해지고 있었다.

변경 코드
func addRound() {
record.round = record.attempts.isEmpty ? record.round : record.round + 1
record.attempts.append(0)
}
record.round를 증가시키는 식을 수정하자 정상적으로 작동하였다.

기존 코드
func start() {
while true {
...
switch selected {
...
case .exit:
...
exit(0)
}
}
}
위 코드 이전에는 isExit 변수를 생성하여 그 변수로 게임의 종료를 결정했었는데, 과제 해설 영상을 보고 exit(0)라는 게 있구나~하면서 바꾸었었다.
하지만 튜터님께서 exit(0)는 프로그램을 강제 종료시키는 함수이기에 GameController에서 호출하기에는 해당 객체의 책임을 벗어나는 일일 수 있다고 조언해주셨다.
main.swift에서 호출해야 더 적절할 것 같다고 피드백주셨는데, 그렇다면 사실 main에서는 게임이 종료되더라도 다른 작업이 일어날 수 있으리라 생각하여 GameController가 게임을 끝내는 방식으로 수정하였다.
변경 코드
func start() {
var isExit = false
while !isExit {
...
switch selected {
...
case .exit:
...
isExit = true
}
}
}
예전에 구현했듯이 isExit 변수를 통해 게임을 종료하도록 수정하였다.