iyOmSd/Title: iOS Think🤔

[iOS] Swift Event - Delegate, Notification, KVO란? (2/3)

냄수 2020. 3. 9. 12:50
반응형

이전 글에서는 

2020/02/25 - [iyOmSd/Title: iOS Think🤔] - Swift Event - Delegate, Notification, KVO란? (1/3)

 

Swift Event - Delegate, Notification, KVO란? (1/3)

제목에서 보는 모든 것들은 이벤트 처리관련 용어들 이에요 모두 이벤트를 처리해주지만 사용 방법이나 쓰이는 용도가 조금 달라요 '별 차이 없는데 아무거나 쓰지 뭐' 라는 생각을 할 수 있는데 iOS를 알아가는데..

nsios.tistory.com

Delegate를 다뤄봤어요

이번에는 Notification을 다뤄볼거에요

 

Notification은...

 

  • Notification Center 싱글턴 객체를 통해서 이벤트 발생여부 등록한 객체에게 post하는 방식

  • 많은줄의 코드가필요없음

  • 다수 객체에게 동시에 이벤트발생 알려줄 수 있음

  • Notification과 관련된 정보를 Any?,object,[AnyHashable: Any]?타입의 userInfo로 전달가능

  • 컴파일시 구독이 잘되고있는지, 올바르게 받아오는지 체크불가능

  • 추적이쉽지않음

 

동작 원리는 아래의 그림과 같아요

그림에서 보이듯

1. 한 객체에서 이벤트가 발생했다는 것을 Notification Center로 송신해요

2. Notification Center에서 발생된 이벤트를 등록된 모든 옵저버에 보내고

3. 해당 이벤트를 구독하는 Observer가 있다면 해당 화면에서 이벤트에 대한 처리를 할 수 있어요

(등록된 옵저버가 많아지면 모든 옵저버리스트를 찾아가기때문에 성능이 저하가 될수있어요)

 

Notification에서 post는 동기적으로 동작해요

a, b의 이벤트를 순서대로 post했다면

a의 옵저버에게 이벤트를 전송하고

a의 옵저버가 일을 다 할때 까지 기다리고

그 다음에 b의 옵저버에게 이벤트를 전송해줘요

 

더 자세한 동작을 확인하려면

2020/11/20 - [iyOmSd/Title: Swift] - [Swift] Notification Center, Notification Queue

이 글을 보고오세요!

 

 

이벤트 Observer 등록
NotificationCenter.default.addObserver(self, selector: #selector(reviewEdit(_:)), name: NSNotification.Name(rawValue: "reviewEdit"), object: nil)

이벤트 수신을 등록하는 부분이에요

selector: 해당 이벤트가 수신되었을때 실행시킬 함수

name: 수신대기할 이벤트의 이름

 

위와 같이 Observer의 이름을 등록 할 수 있지만

재사용과 수정에 있어서 불편함이 있어요 그래서 아래처럼

extension을 이용해서 이름을 관리하는 좋은 방법이 있어요

extension Notification.Name {
    static let reviewEdit = Notification.Name("reviewEdit")
}

// 수정된 addObserver
NotificationCenter.default.addObserver(self, selector: #selector(reviewEdit(_:)), name: .reviewEdit, object: nil)

 

이벤트 송신
let reviewInfo = ReviewInfo()
NotificationCenter.default.post(name: .reviewEdit, object: reviewInfo)

이벤트 송신하는 부분이에요

name: 송신할 이벤트의 이름

object: 같이 전달할 object, 없으면 nil

이 코드가 실행되면 .reviewEdit의 이름을 가지고 수신대기중인 Observer에게 수신되요

 

이벤트 수신시 실행될 함수 selector
@objc func reviewEdit(_ notification: Notification) {
	guard let reviewInfo = notification.object as? ReviewInfo else {
    	return
    }
}

저 같은경우는 위에서 reviewInfo라는 ReviewInfo타입 object를 같이 전달했어요

notification.object로 이 값에 접근하여 알맞게 형변환을 해주고 안의 데이터를 사용할 수 있어요

 

이벤트 Observer 제거
NotificationCenter.default.removeObserver(self, name: .reviewEdit, object: nil)

옵저버는 계속 살아있기 때문에

옵저버를 등록해서 사용했으면

화면이 꺼질때는 메모리 낭비를 막기위해서 해제를 해줘야해요

iOS9 이상부터는 자동으로 해제를 해줘서 따로 구현을 안해도되요

 

 

 

 

Delegate와 Notification을 간단하게 비교해 볼까요??

Delegate Notification
  • 제3의 객체가 필요 없음

  • 다수 객체들에게 이벤트발생 전달 어렵고 비효율적
  • 엄격한 Syntax, 메소드 명확하게 명시
  • Notification Center 싱글턴 객체를 통해서 이뤄짐

  • 다수 객체에게 동시에 이벤트발생 전달 가능
  • 컴파일시 추적이 어려움

 

어느 상황에 Delegate를 쓰고 어느 상황에 Notification을 써야하는지 생각을 해볼 필요가 있는 것 같아요

이 글은 저의 주관이므로 다른 답이 있을 수도 있고 틀린 부분이 있을수도 있어요!!

 

Delegate는 한 화면에서 많은 이벤트와, 해당되는 객체의 데이터를 가져와야할 때 쓰면 적합하다고 생각해요

TableView의 Delegate함수를 보면 셀 갯수, 셀 설정, 셀 크기, 등

많은 이벤트를 위한함수와, 이벤트가 발생했을 때 가져올 수 있는 데이터에 접근하기위한 변수들이 설정 되어있잖아요??

그렇듯 한 속성에대한 다양한 이벤트를 처리하기 위해서는 Delegate가 적합하다고 생각해요

 

Notification은 한 이벤트에 대해 다수의 수신자가 있을 경우에 쓰면 좋을 것 같아요

UI의 업데이트를 위한 이벤트를 받을 때,

화면간 연결관계가 없을 때,

바로다음 화면이아닌 건너건너 depth가 깊은 화면에 이벤트를 줄 때 좋을 것 같아요

depth가 깊다면 Delegate를 채택하고 객체를 담을 변수를 전달하는 과정이 복잡하다고 생각해요

 

 

 

다음글에서는 마지막으로 KVO에 대해서 알아볼게요 :)

2020/03/28 - [iyOmSd/Title: iOS Think🤔] - Swift Event - Delegate, Notification, KVO란? (3/3)

 

Swift Event - Delegate, Notification, KVO란? (3/3)

앞서 게시글에서 Delegate, Notification에대해 알아봤어요!! 간단하게 다시 리마인드를 하자면 Delegate - 위임자, 대리자 Notification - broadcast 이벤트 엿죠?!? 이번 게시글에서는 마지막으로 KVO에 대해서..

nsios.tistory.com

 

반응형