ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift3의 Access Control] - open Class가 뭐야?
    앱등이에게 살충제를 뿌린다./Swift 2017. 1. 11. 15:32

    <넘나 갖고픈 YAMAHA LL16>



    UIApplication클래스의 shared라는 프로퍼티를 찾아보니 이렇게 적혀있었다.

    그래서 open class가 뭔지를 찾아보니 이렇게 꿀정리가~

    스위프트 3 액세스 제어

    기존의 private은 정의한 스코프(scope)내에서 즉, 같은 중괄호 { } 내에서만 접근을 허용하도록 좀 더 엄격한 의미로 바뀌었습니다. 대신 새로운 fileprivate가 추가되었고 기존의 스위프트 2에서의 private과 같은 의미로 사용됩니다.

    보통 이전에 private 으로 정의된 변수나 메서드는 같은 소스파일에 정의된 익스텐션에서 접근할 수 있었으나 더 이상 그렇게 할 수 없습니다. 따라서 이렇게 접근되어야하는 변수나 메서드를 fileprivate으로 수정해야합니다. 이름이 좀 이상하기는 하지만 크리스 래트너(Chris Lattner)가 직접 제안한 내용입니다.

    Chris Lattner는 Clang과 스위프트와 같은 LLVM과 관련된 컴파일러 프로젝트의 메인 개발자입니다.

    public도 더 엄격해져서 외부에서 호출하는 관점에서는 이전과 동일하지만 클래스의 상속이나 메서드의 오버라이드를 하는 관점에서는 이전과 달라졌습니다. 즉, 같은 모듈이 아닌 외부에서 호출은 가능하지만 상속이나 오버라이드는 불가능합니다. 이 것을 가능하게 하려면 open으로 선언해야 같은 모듈이 아닌 외부에서 상속이 가능해집니다. 메서드의 경우에도 오버라이드를 허용하려면 open으로 정의해야합니다.

    • open open으로 선언된 클래스와 클래스의 멤버에 대해서는 같은 모듈내에서나 이 모듈을 임포트(import)한 다른 모듈에서 접근할 수 있습니다. 접근만 아니라 open 클래스를 상속할 수 있고 open 클래스 멤버를 오버라이드(override)할 수 있습니다.
    • public open과 마찬가지로 어떤 모듈에서든 접근할 수 있습니다. 하지만 상속과 오버라이딩은 좀 더 제한적입니다. public 클래스에 대해서는 같은 모듈 내에서만 상속이 가능합니다. public 멤버를 오버라이드하는 것도 동일 모듈에서만 허용됩니다. 만약 프레임워크를 만든다면 public과 open의 차이를 구별해서 사용하는 것이 중요합니다. 프레임워크의 사용자가 서브 클래스를 만들거나 메서드를 오버라이드할 수 있도록 허용하려면 open으로 선언해야합니다.
    • internal 같은 모듈 내에서만 접근을 허용합니다. 모듈의 외부에서는 접근할 수 없습니다. 디폴트 액세스 레벨입니다.
    • fileprivate 같은 소스 파일 내부에서만 접근이 가능합니다.
    • private 선언된 스코프 내에서만 접근이 가능합니다.

    Objective-C 클래스들은 open으로 임포트됩니다.

    기존의 코드를 스위프트 3로 변경하면서 가장 먼저 부딪히는 문제는 private의 변경사항이라고 생각됩니다. 같은 소스코드 내에서 하나의 클래스의 내용을 기능별로 익스텐션(extension)으로 나누어 구현하는 방법을 자주 사용하는 편인데 예를 들면 다음과 같은 경우입니다.

    class MyClass {
    	private var message: String = "Hello"
    }
    	
    extension MyClass {
    	func sayHello() {
    		print(message)
    	}
    }
    

    스위프트 2.x 코드에서는 클래스의 멤버 변수들을 private으로 선언하고 클래스의 다양한 메서드들을 기능별로 분류하여 각각을 익스텐션을 구룹지어 작성하였습니다. 이렇게 해도 private 변수인 message를 각각의 익스텐션 내에서 (같은 소스파일내에 있으므로) 접근이 가능했었습니다. 하지만 스위프트 3에서는 private은 정의된 스코프 (여기 예에서는 원래의 MyClass정의 범위) 내에서만 접근이 가능하게 되므로 익스텐션의 sayHello() 메서드 내에서는 message에 접근할 수 없게 됩니다. 그러므로 위에서 소개한 것처럼 message 멤버 변수를 fileprivate으로 변경해야만 합니다.



    출처 : https://outofbedlam.github.io/swift/2016/11/12/SwiftAccessControl/


Designed by Tistory.