Swift public / private 외 다른 접근 제어자
안녕하세요.
정말 오랜만입니다.
요즘 일 때문에 부쩍 바빠지다보니 8월에는 글조차 작성하지 못했네요.
오늘은 업무때문에 공부하다가 알게 된 짧은 정보가 있어서 정리해볼까 합니다.
오늘의 주제는 접근제어자(접근제어지시자)입니다.
* 접근제어자(접근제어지시자)란?
- 해당 함수 혹은 클래스 의 접근 가능 범위를 설정해주는 친구입니다.
- 주로 내가 만든 걸 사용할 때 어디까지 허용해 줄것인지를 설정을 해줍니다.
* 이걸 굳이 왜 사용하나요?
: 보통 특정값이 바뀌면 안되서 사용에 제한을 걸거나
반대로 사용자가 사용할수있게 제한을 풀어주기위해 사용합니다.
사실 제일 유명한 친구 둘은 이미 대부분 보셨을 겁니다.
* Public
: 프로젝트내에 어디든 접근이 가능합니다.
: 외부에서도 접근이 가능합니다.
* Private
: 선언한 범위내에서만 사용이 가능합니다.
: 같은 파일에 있더라도 선언된 클래스가 다른경우 사용할 수 없습니다.
예를들면 아래 같은 클래스에 둘다 있다면
앞에 public 이 적힌건 testPub는 문제없이 사용할 수 있지만
private 이 적힌건 testPri는 다른 곳에서 사용할수없습니다.
class A{
public func testPub(){
print("안녕")
}
private func testPri(){
print("Hello")
}
}
let aClass = A()
aClass.testPub() //사용 가능
//aClass.testPri() // 사용 불가
그런데 혹시 이상한 거 눈치채셨나요?
Xcode 에서 함수나 클래스를 접근제어자 없이 선언하면
프로젝트 전체에서 사용이 가능합니다.
그래서 기본이 Public 이라고 생각하게됩니다.
하지만! 실제 해당 파일을 라이브러리로 만들어서
제 3자에게 제공을 하면 해당 기능을 사용할 수 없습니다.
그럼 기본으로 설정되는 제어자는 무엇일까요?
* internal
internal func test(){} // xcode 기본 설정
: 바로 이 친구가 기본으로 설정되는 접근 제어지시자입니다.
: 같은 프로젝트 범위에서만 사용할 수 있도록 설정해줍니다.
: 엄연히 Public 과는 다른 기능입니다.
이 외에도 좀더 추가로 설명드리면
* fileprivate
fileprivate func testPri(){}
: 이 친구는 위 internal보다는 좁은 범위로 사용되는 지시자입니다.
: 같은 파일에서만 접근이 가능합니다.
Q.그럼 Public 보다 더 개방적인 친구는 없나요?
A.놀랍게도 Open이라는 친구가 있습니다.
* open
open class Food{
open func taste(){
print("Good")
}
}
class Candy : Food{
override func taste(){
print("Sweet")
}
}
let canndy = Candy()
canndy.taste()
//결과값 : Sweet
: 위에 처음엔 Good이 나오게 했던 함수를 Override를 통해 Sweet이 나오도록 바꾼겁니다.
: 다르게말하면 변형도 허용한다고 보시면 되겠습니다.
: 참고로 open을 선언시에는 위처럼 함수뿐 아니라 클래스도 open 으로 선언해야 가능합니다.
Q. 근데 public 도 저렇게 쓸 수 있자나요?
A. 맞습니다. 위 예제는 사실 public과 open 둘다 가능합니다. (같은 내부에 있기 때문)
아무래도 샘플 코드 상으로는 차이가 안와닿겠지만
예를 들어 위 클래스가 라이브러리이고 이걸 사용하는 사용자가 (제3자의 외부 접근)
위 클래스를 오버라이딩해서 쓰는 건 open일때만 가능하다는 이야기 입니다.
전체적으로 정리하면 이런 모양이 될 것 같네요.
선언한 범위내 | 같은 파일 | 같은 프로젝트 | 외부 라이브러리 | 제3자 변형 가능 | |
Open | O | O | O | O | O |
Public | O | O | O | O | X |
Internal | O | O | O | X | X |
FilePrivate | O | O | X | X | X |
Private | O | X | X | X | X |
* 번외
Q. 가끔 @objc 라는 명령어가 보이던데 이것도 비슷한 건가요?
A. 이 친구를 라이브러리에서 선언하게되면 swift 코드임에도 불구하고
해당 기능을 ObjC 프로젝트에서 사용할 수 있게 도와줍니다.
그러다보니 swift에서만 가능한 기능을 넣으면 오류가 날수있으니 주의가 필요합니다 (EX) [enum])
후 진짜 간만에 글을 쓰는건데
여유가 되는 날엔 이런 기본 개념을 정리하는것도
좋은 것 같네요.
(아마 다음글도 기초 관련 글 일 듯한...)
다음 여유가 되는 날에 다시 돌아오겠습니다.
오늘도 파이팅입니다.