develop

Declaration Attributes 본문

iOS

Declaration Attributes

pikachu987 2021. 1. 19. 19:55
반응형

@objc

Swift에서 objc 라는 키워드는 심볼을 Objective-C 네임스페이스에 알려주는 역활이다.

Objective-C에서 Swift를 찾을수 없게 되어 있는데 찾을수 있게 해주는 것이 objc 키워드 이다.

 

Selector

self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.doneTap(_:)))

private func doneTap(_ sender: UIBarButtonItem) {

}

이렇게 적으면 Argument of '#selector' refers to instance method 'doneTap' that is not exposed to Objective-C 라고 에러가 난다.

@objc를 추가해주면 된다.

@objc private func doneTap(_ sender: UIBarButtonItem) {

}

Swift에서 #selector는 Objective-C 메소드여야 하기 때문에 @objc를 붙여줘야 한다.

 

Class Method

@objc(PKCMYViewContoller)
class MyViewController: UIViewController {

    @objc(pkcFetchData)
    func fetchData() {

    }
}

Swift는 모듈내에 존재하는 class나 extension에 동일한 메서드명을 가진게 존재할 경우 바로 컴파일 에러가 발생해서 prefix를 안붙여도 된다.Objective-C에서는 컴파일 에러가 아니라 그냥 빌드되고 같은 이름의 아무 클래스나 메서드가 불려진다.

그래서 @objc로 Objective-C에서 사용할 클래스명, 메서드명을 바꿔준다.

 

@escaping

2021/01/04 - [iOS] - Escaping noescaping 참조

 

@autoclosure

func someFunction(_ closure: () -> Void) {
    print("someFunction1")
    closure()
}
someFunction { print("Hello1") }
someFunction({ print("Hello2") })

클로져를 사용하면 위의 코드와 같이 사용할 것이다.

하지만 몇몇 라이브러리들을 보면

someFunction(print("Hello1"))

이렇게 사용하는 것을 볼 수 있다.

someFunction에 저렇게 사용하면 Cannot convert value of type '()' to expected argument type '() -> Void'라는 에러가 나온다.

 

@autoclosure를 사용하여 someFunction2(print("Hello3")) 가 되게 할수 있다.

func someFunction2(_ closure: @autoclosure () -> Void) {
    print("someFunction2")
    closure()
}

someFunction2(print("Hello3"))

 

비동기 실행이나 클로져를 저장해서 사용할 경우 @escaping를 추가 해줄 수도 있다.

func someFunction2(_ closure: @escaping @autoclosure () -> Void) {
    print("someFunction2")
    DispatchQueue.main.async {
        closure()
    }
}

someFunction2(print("Hello3"))

 

@discardableResult

let textField = UITextField()
let isComplete = textField.resignFirstResponder()
textField.resignFirstResponder()

텍스트필드에 resignFirstResponder라는 메서드가 있다.이 메서드는 리턴값이 있는데 리턴값을 변수로 저장하거나 사용하지 않아도 Result of call to '' is unused 라는 경고창이 뜨지 않는다.

@discardableResult
func example() -> Bool {
    return true
}

이렇게 @discardableResult를 써주면 값을 사용하지 않아도 경고창이 뜨지 않는다.

값이 필요할 수도 있고 값이 필요 없을 수도 있는 메서드에 사용하면 경고창이 뜨지 않아서 좋다.

반응형

'iOS' 카테고리의 다른 글

Generic  (0) 2021.01.21
Throttle, Debounce  (0) 2021.01.20
DispatchGroup  (0) 2021.01.18
final Keyword  (0) 2021.01.17
Standard Library Protocol  (0) 2021.01.16
Comments