답변:
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에서 수락 및 이행되었습니다.
foo()
통화에 적용됩니다 .
나는 private , fileprivate , open 및 public에 대한 다이어그램을 그립니다.
텍스트 설명은 Martin R 의 답변을 참조하십시오.
[스위프트 4 업데이트]
fileprivate
하십시오, 확장명에 연결되어 있지 않지만 파일에 연결되어 있습니다 (다른 파일에 클래스 A의 확장명을 작성하면 fileprivate
멤버를 사용할 수 없습니다 )
public
상속 할 수 없으므로 세 번째 이미지가 올바르지 않습니다. 또한 볼 수 있으면 언제든지 모든 클래스에 확장을 둘 수 있습니다. 확장에 대한 가시성을 설명하는 것은 좋은 생각이 아닙니다.
실제 경험의 규칙은 클래스 / 구조체 선언에서만 사용되는 변수, 상수, 내부 구조체 및 클래스에 대해 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는 서브 클래스에서 액세스 할 수 있습니다.
스위프트 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 : 개인 인스턴스가 함수 본문에서 선언되면 인스턴스 범위는 함수 본문으로 제한됩니다.
다음 예에서 언어 구조에 의해 수정 private
과 fileprivate
동일하게 작동하는 것 :
fileprivate func fact(_ n: Int) -> Int {
if (n == 0) {
return 1
} else {
return n * fact(n - 1)
}
}
private func gauss(_ n: Int) -> Int {
if (n == 0) {
return 0
} else {
return n + gauss(n - 1)
}
}
print(fact(0))
print(fact(5))
print(fact(3))
print(gauss(10))
print(gauss(9))
이것은 직감에 따른 것 같습니다. 그러나 예외가 있습니까?
친절한 관계.
class Privacy {
fileprivate(set) var pu:Int {
get {
return self.pr
}
set {
self.pr = newValue
}
}
private var pr:Int = 0
fileprivate var fp:Int = 0
func ex() {
print("\(self.pu) == \(self.pr) and not \(self.fp)")
}
}
extension Privacy {
func ex2() {
self.pu = 5
self.ex()
}
}
ivar에게는 매우 간단하기 때문에 이것을 좋아합니다.
fileprivate를 private으로 변경하거나 그 반대로 변경하여 컴파일시 어떤 일이 발생하는지 확인하십시오 ...
private
로fileprivate
. 당신이 손으로 그 일의 고급 스러움이있는 경우 그러나, 당신은 종종 떠나 혜택을 누릴 수 있습니다private
으로private
... 그것은 컴파일하는 경우, 모든 좋은.