호댕의 iOS 개발

[iOS] 사용하지 않는 코드를 사용하지 못하도록 하려면?! (@available) 본문

Software Engineering/iOS

[iOS] 사용하지 않는 코드를 사용하지 못하도록 하려면?! (@available)

호르댕댕댕 2022. 3. 18. 18:29

만약 다른 사람들이 특정 코드를 사용하지 못하도록 하려면 어떻게 처리를 해줘야 할까? 

 

예를 들어 이런 코드가 있다고 생각을 해보자. 

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

해당 코드는 스토리보드에서 ViewController를 생성할 때 호출되는 생성자이다. 

 

만약 따로 생성자를 정의하면서 required init?을 불가피하게 생성을 했다고 가정한다면 required init?은 다른 곳에선 사용을 하지 못하게 해야 한다. 

 

required init을 통해 VC를 생성하지 않고 따로 정의한 생성자로 VC를 생성해야 하기 때문이다. 

 

이때는 available attribute를 사용하면 된다.

 

🔸 available attribute

available attribute를 통해 어떤 플랫폼, 버전에서 사용이 가능한지를 지정해줄 수 있다. 

해당 attribute를 통해 특정 플랫폼, 특정 버전에서만 사용이 가능한 메서드도 정의할 수 있는 것이다. 

 

만약 * 로 표시를 한다면 모든 플랫폼을 의미한다. 

즉, 아래 있는 플랫폼을 전부 사용할 수 있다는 것이다. 

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • macCatalyst
  • macCatalystApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension
  • swift

버전의 경우 *(asterisk)를 사용할 수 없다. 

 

또한 다음과 같은 매개변수를 통해 특정 메서드나 타입, 프로토콜 등에 대한 정보를 제공할 수 있다. 

 

▪️ introduced

지정된 플랫폼이나 언어에서 언제 도입이 되었는지를 의미함.

introduced: version number

▪️ deprecated

지정한 플랫폼이나 언어에서 언제부터 사용되지 않는지를 의미함.

버전 번호의 경우 1~3개까지의 양수로 표현이 되며 버전 번호를 생략하게 되면 사용이 중단된 시기에 대해 알려주지 않고, 현재 사용이 중단되었다고 표시해준다. 

해당 버전 이상일 경우 메서드를 호출하면 warning이 뜨게 된다. 

deprecated: version number

다만 버전을 직접 명시해줄 경우 플랫폼을 특정해서 명시해줘야 한다. 안그러면 어떤 플랫폼의 버전인지 특정할 수 없어 warning이 발생한다.

Unexpected version number in 'available' attribute for non-specific platform '*'

 

만약 모든 플랫폼에서 deprecated를 사용하고 싶다면 아래처럼 적어주면 된다. 

@available(*, deprecated)

▪️ obsoleted

지정된 플랫폼이나 언어에서 언제부터 사용이 폐기되었는지를 의미함.

따라서 이렇게 선언이 되어있으면 더이상 아예 사용을 할 수가 없다는 것을 의미한다.

 

따라서 이를 사용하면 컴파일 에러가 발생한다. 

obsoleted: version number

▪️ message

문자 그대로 더이상 사용되지 않거나 아예 폐기된 것을 사용했을 때 warning 또는 컴파일 에러를 내보내면서 컴파일러가 표시할 메세지를 정의한다. 

message: message

▪️ renamed

해당 선언의 이름이 바뀐 경우 새로운 이름을 보여준다.

renamed: new name

 

 

따라서 위에서 선언한 메서드를 사용하지 못하게 하기 위해선 아래 코드처럼 작성을 해주면 된다. 

@available(*, unavailable)
required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

이렇게 하면 모든 플랫폼에서 사용할 수 없도록 하여 만약 해당 init을 통해 생성을 하려고 하면 아래 그림과 같은 컴파일 에러가 발생한다. 

 

 

Comments