[swift] Swift3에서 fileprivate과 private을 구별하는 좋은 예는 무엇입니까?

기사 는의 새로운 액세스 지정자를 이해하는 데 도움이되었습니다 Swift 3. 또한 서로 다른 용도의 몇 가지 예 제공 fileprivateprivate.

내 질문은- 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방법은 동일한 소스 파일에서 액세스 할 수 있습니다.

노트:

  1. 제안 SE-0159 – 수정 개인 액세스 수준은 신속한 진화 메일 링리스트에 긴 논쟁적인 토론 후 스위프트 4의 스위프트 2 의미로 되돌릴 제안은 제안했다 거절 .

  2. 제안 SE-0169은 – 개인 선언 및 확장 사이의 상호 작용을 향상을 만들기 위해 제안 private
    확장이 정의되어있는 경우 동일한 유형의 확장에 액세스 할 수있는 형식 안에 선언을 동일한 소스 파일입니다.
    이 제안은 Swift 4에서 수락 및 이행되었습니다.


답변

나는 private , fileprivate , openpublic에 대한 다이어그램을 그립니다.

텍스트 설명은 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 : 개인 인스턴스가 함수 본문에서 선언되면 인스턴스 범위는 함수 본문으로 제한됩니다.