이 기사 는의 새로운 액세스 지정자를 이해하는 데 도움이되었습니다 Swift 3
. 또한 서로 다른 용도의 몇 가지 예 제공 fileprivate
및 private
.
내 질문은- fileprivate
이 파일에서만 사용할 함수에서 사용하지 않는 것 private
입니까?
답변
fileprivate
무엇 지금 private
같은 소스 파일에서 액세스 : 이전 스위프트 릴리스에서 사용. 로 표시된 선언 private
은 선언 된 어휘 범위 내에서만 액세스 할 수 있습니다. 따라서 private
보다 제한적 fileprivate
입니다.
현재 스위프트 4, 확장이 같은 소스 파일에 정의 된 경우 유형 내 개인 선언은 동일한 유형의 확장에 액세스 할 수 있습니다.
예 (하나의 소스 파일에 모두 있음) :
class A {
private func foo() {}
fileprivate func bar() {}
func baz() {
foo()
bar()
}
}
extension A {
func test() {
foo() // Swift 3: error: use of unresolved identifier 'foo'
// Swift 4: no error because extension is in same source file
bar()
}
}
let a = A()
a.foo() // error: 'foo' is inaccessible due to 'private' protection level
a.bar()
-
개인용
foo
메소드는class A { ... }
정의 범위 내에서만 액세스 할 수 있습니다 . 확장에서 유형으로도 액세스 할 수 없습니다 (Swift 3에서 Swift 4의 변경 사항은 아래 두 번째 참고 참조). -
파일 개인
bar
방법은 동일한 소스 파일에서 액세스 할 수 있습니다.
노트:
-
제안 SE-0159 – 수정 개인 액세스 수준은 신속한 진화 메일 링리스트에 긴 논쟁적인 토론 후 스위프트 4의 스위프트 2 의미로 되돌릴 제안은 제안했다 거절 .
-
제안 SE-0169은 – 개인 선언 및 확장 사이의 상호 작용을 향상을 만들기 위해 제안
private
확장이 정의되어있는 경우 동일한 유형의 확장에 액세스 할 수있는 형식 안에 선언을 동일한 소스 파일입니다.
이 제안은 Swift 4에서 수락 및 이행되었습니다.
답변
나는 private , fileprivate , open 및 public에 대한 다이어그램을 그립니다.
텍스트 설명은 Martin R 의 답변을 참조하십시오.
[스위프트 4 업데이트]
답변
실제 경험의 규칙은 클래스 / 구조체 선언에서만 사용되는 변수, 상수, 내부 구조체 및 클래스에 대해 private을 사용한다는 것입니다. 클래스 / 구조와 동일한 파일 내에서 정의 된 중괄호 (예 : 어휘 범위) 외부에서 확장 내에서 사용되는 항목에 대해 fileprivate를 사용합니다.
class ViewController: UIViewController {
@IBOutlet var tableView: UITableView!
//This is not used outside of class Viewcontroller
private var titleText = "Demo"
//This gets used in the extension
fileprivate var list = [String]()
override func viewDidLoad() {
navigationItem.title = titleText
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return list.count
}
}
답변
Swift 4.0에서는 이제 Private에서 확장명으로 액세스 할 수 있지만 동일한 파일 내에서 액세스 할 수 있습니다. 다른 파일에서 확장명을 선언 / 정의하면 확장에 개인 변수에 액세스 할 수 없습니다 **
파일 개인
파일 개인 액세스는 엔티티 사용을 자체 정의 소스 파일로 제한합니다. 파일 개인 액세스를 사용하여 세부 사항이 전체 파일 내에서 사용될 때 특정 기능의 구현 세부 사항을 숨기십시오.
구문 : fileprivate <var type> <variable name>
예 : fileprivate class SomeFilePrivateClass {}
개인
개인 액세스는 엔터티 사용을 엔 클로징 선언 및 동일한 파일에있는 해당 선언의 확장으로 제한 합니다 . 세부 사항이 단일 선언 내에서만 사용되는 경우 개인 액세스를 사용하여 특정 기능의 구현 세부 사항을 숨기십시오.
구문 : private <var type> <variable name>
예 : private class SomePrivateClass {}
모든 액세스 수준에 대한 자세한 내용은 다음과 같습니다. Swift-액세스 수준
이 이미지를보십시오 :
File : ViewController.swift
확장과 뷰 컨트롤러는 모두 같은 파일에 있으므로, 개인 변수 testPrivateAccessLevel
는 확장에서 접근 할 수 있습니다
File : TestFile.swift
확장과 뷰 컨트롤러는 서로 다른 파일에 있으므로, 개인 변수 testPrivateAccessLevel
는 확장에 접근 할 수 없습니다.
여기서 class ViewController2
는의 서브 클래스 ViewController
이며 둘 다 동일한 파일에 있습니다. 여기서 개인 변수 testPrivateAccessLevel
는 서브 클래스에서 액세스 할 수 없지만 fileprivate는 서브 클래스에서 액세스 할 수 있습니다.
답변
@MartinR과 @StephenChen의 답변은 완벽하지만 Swift 4 는 약간 변경합니다.
Private 은 이제 클래스가 선언 된 클래스와 확장 클래스에 대해 private으로 간주됩니다.
FilePrivate 는 변수가 정의 된 클래스, 확장명 또는 동일한 파일에 정의 된 다른 클래스이기 때문에 해당 파일에서 개인용으로 간주됩니다.
답변
스위프트 5 업데이트
비공개 대 FilePrivate
명확성을 높이기 위해 코드 스 니펫을 놀이터에 붙여 넣기
class Sum1 {
let a: Int!
let b: Int!
private var result: Int?
fileprivate var resultt: Int?
init(a : Int, b: Int) {
self.a = a
self.b = b
}
func sum(){
result = a + b
print(result as! Int)
}
}
let aObj = Sum1.init(a: 10, b: 20)
aObj.sum()
aObj.resultt //File Private Accessible as inside same swift file
aObj.result //Private varaible will not be accessible outside its definition except extensions
extension Sum1{
func testing() {
// Both private and fileprivate accessible in extensions
print(result)
print(resultt)
}
}
//If SUM2 class is created in same file as Sum1 ---
class Sum2{
func test(){
let aSum1 = Sum1.init(a: 2, b: 2)
// Only file private accessible
aSum1.resultt
}
}
참고 : Swift 파일 외부에서는 개인 및 파일 개인 모두에 액세스 할 수 없습니다.
답변
filePrivate- 액세스 제어 레벨이 파일 내에 있습니다.
사례 1 : 동일한 클래스 파일로 확장자를 작성하고 확장자로 fileprivate 함수 또는 fileprivate 특성에 액세스하려고 시도-액세스 허용
사례 2 : 새 파일에서 클래스 확장자를 작성하는 경우-이제 fileprivate 함수 또는 fileprivate에 액세스하십시오 재산-접근 금지
개인용 액세스 제어 수준은 어휘 범위에 있습니다
case 1 : 클래스에서 속성 또는 함수가 private으로 선언 된 경우 범위는 기본적으로 클래스입니다.
case 2 : 개인 인스턴스가 함수 본문에서 선언되면 인스턴스 범위는 함수 본문으로 제한됩니다.