Swift có sửa đổi truy cập không?


273

Trong dữ liệu đối tượng Objective-C có thể public, protectedhoặc private. Ví dụ:

@interface Foo : NSObject
{
  @public
    int x;
  @protected:
    int y;
  @private:
    int z;
  }
-(int) apple;
-(int) pear;
-(int) banana;
@end

Tôi không tìm thấy bất kỳ đề cập nào về các sửa đổi truy cập trong tài liệu tham khảo Swift. Có thể giới hạn khả năng hiển thị của dữ liệu trong Swift?


Tôi cũng không. Apple ít nhất nên giới thiệu nghi thức cho các tư nhân, như trong python họ có tiền tố gạch dưới.
Ciantic

Đã thêm câu trả lời được cập nhật cho phiên bản cuối cùng của Xcode 6.1.1
holroy

Câu trả lời:


419

Kể từ Swift 3.0.1 , có 4 cấp độ truy cập , được mô tả bên dưới từ mức cao nhất (hạn chế thấp nhất) đến mức thấp nhất (hạn chế nhất).


1. openpublic

Cho phép một thực thể được sử dụng bên ngoài mô-đun xác định (mục tiêu). Bạn thường sử dụng openhoặc publictruy cập khi chỉ định giao diện chung cho khung.

Tuy nhiên, opentruy cập chỉ áp dụng cho các lớp và thành viên lớp và nó khác với publictruy cập như sau:

  • public các lớp và các thành viên lớp chỉ có thể được phân lớp và ghi đè trong mô đun xác định (đích).
  • open các lớp và các thành viên lớp có thể được phân lớp và ghi đè cả bên trong và bên ngoài mô đun xác định (đích).

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2. internal

Cho phép một thực thể được sử dụng trong mô-đun xác định (đích). Bạn thường sử dụng internalquyền truy cập khi xác định cấu trúc bên trong của ứng dụng hoặc khung.

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3. fileprivate

Hạn chế việc sử dụng một thực thể đối với tệp nguồn xác định của nó. Bạn thường sử dụng fileprivatequyền truy cập để ẩn chi tiết triển khai của một phần chức năng cụ thể khi các chi tiết đó được sử dụng trong toàn bộ tệp.

// First.framework – A.swift

internal struct A {

    fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4. private

Hạn chế việc sử dụng một thực thể để khai báo kèm theo. Bạn thường sử dụng privatequyền truy cập để ẩn chi tiết triển khai của một chức năng cụ thể khi các chi tiết đó chỉ được sử dụng trong một khai báo.

// First.framework – A.swift

internal struct A {

    private static let x: Int

    internal static func doSomethingWithX() {
        x // ok
    }

}

A.x // error: x is unavailable

37
Ai đó có thể giải thích cho tôi tại sao đây không phải là một vấn đề lớn?
Zaky Đức

15
luôn luôn là một số phương pháp hoặc các biến trong OOP rằng nên tin hay bảo vệ. Điều này cho phép thực hiện thiết kế RẮN , vì các phương thức lớn được chia cho một số phương pháp nhỏ hơn, mỗi phương thức có trách nhiệm riêng, có thể được ghi đè, nhưng chỉ có phương pháp "chính" để sử dụng công khai.
akashivskyy

19
Cá nhân tôi không thích các giải pháp như giải pháp với các phương pháp "riêng tư" hàng đầu / đặc biệt. Ngay cả khi nó được đảm bảo rằng bản thân tôi sẽ là người duy nhất từng xem mã này, nó làm cho mã tiết kiệm hơn / ít bị lỗi hơn vì trình biên dịch sẽ đơn giản ngăn bạn làm những việc bạn không nên làm. Vì vậy, tôi nghĩ rằng họ nên thoát khỏi "cơ chế kiểm soát truy cập" càng nhanh càng tốt, để mọi người không quen với những thói quen xấu.
Jonas Eschmann

10
Ghi chú phát hành beta Xcode 6 cho biết: "Kiểm soát truy cập (thành viên công cộng / riêng tư) không được bật trong hạt giống này. (15747445)"
Martin Ullrich

9
@alcalde Ý tưởng về giao diện công cộng rất có giá trị. Nếu bạn dự định rằng tất cả các mã trong một lớp phải nằm trong các hàm là một phần của API công khai, tôi nghĩ điều đó khá hạn chế. Mặt khác, việc có một API công khai được chỉ định cho phép việc triển khai thay đổi (bao gồm cả việc sử dụng các phương thức riêng tư) mà không làm gián đoạn người tiêu dùng. Nếu ai đó 'cần' sử dụng phương thức lớp bên trong, tôi cảm thấy họ đang hiểu sai giới hạn của chức năng của lớp (hoặc đang cố sử dụng lớp lỗi).
jinglểula

26

Swift 4 / Swift 5

Theo đề cập trong Tài liệu Swift - Kiểm soát truy cập , Swift có 5 Điều khiển truy cập :

  • mở công khai : có thể được truy cập từ các thực thể của mô-đun của chúng và bất kỳ thực thể nào của mô-đun nhập mô-đun xác định.

  • nội bộ : chỉ có thể được truy cập từ các thực thể mô-đun của họ. Đây là cấp độ truy cập mặc định.

  • fileprivate private : chỉ có thể được truy cập giới hạn trong phạm vi giới hạn nơi bạn xác định chúng.



Sự khác biệt giữa mởcông cộng là gì?

open giống như công khai trong các phiên bản trước của Swift, chúng cho phép các lớp từ các mô-đun khác sử dụng và kế thừa chúng, tức là: chúng có thể được phân lớp từ các mô-đun khác. Ngoài ra, họ cho phép các thành viên từ các mô-đun khác sử dụng và ghi đè lên chúng. Logic tương tự đi cho các mô-đun của họ.

công cộng cho phép các lớp từ mô-đun khác sử dụng chúng, nhưng không kế thừa chúng, tức là: chúng không thể được phân lớp từ các mô-đun khác. Ngoài ra, họ cho phép các thành viên từ các mô-đun khác sử dụng chúng, nhưng KHÔNG ghi đè lên chúng. Đối với các mô-đun của chúng, chúng có cùng logic mở (chúng cho phép các lớp sử dụng và kế thừa chúng; Chúng cho phép các thành viên sử dụng và ghi đè lên chúng).


Sự khác biệt giữa fileprivateprivate là gì?

fileprivate có thể được truy cập từ toàn bộ tập tin của họ.

riêng tư chỉ có thể được truy cập từ khai báo duy nhất của họ và đến phần mở rộng của khai báo đó trong cùng một tệp; Ví dụ:

// Declaring "A" class that has the two types of "private" and "fileprivate":
class A {
    private var aPrivate: String?
    fileprivate var aFileprivate: String?

    func accessMySelf() {
        // this works fine
        self.aPrivate = ""
        self.aFileprivate = ""
    }
}

// Declaring "B" for checking the abiltiy of accessing "A" class:
class B {
    func accessA() {
        // create an instance of "A" class
        let aObject = A()

        // Error! this is NOT accessable...
        aObject.aPrivate = "I CANNOT set a value for it!"

        // this works fine
        aObject.aFileprivate = "I CAN set a value for it!"
    }
}



Sự khác biệt giữa Swift 3 và Swift 4 Access Control là gì?

Như đã đề cập trong đề xuất SE-0169 , sự tinh chỉnh duy nhất đã được thêm vào Swift 4 là phạm vi kiểm soát truy cập riêng tư đã được mở rộng để có thể truy cập được từ các phần mở rộng của tuyên bố đó trong cùng một tệp; Ví dụ:

struct MyStruct {
    private let myMessage = "Hello World"
}

extension MyStruct {
    func printMyMessage() {
        print(myMessage)
        // In Swift 3, you will get a compile time error:
        // error: 'myMessage' is inaccessible due to 'private' protection level

        // In Swift 4 it should works fine!
    }
}

Vì vậy, không cần phải khai báo myMessagefileprivate để có thể truy cập được trong toàn bộ tệp.


17

Khi một người nói về việc tạo ra một "phương thức riêng tư" trong Swift hoặc ObjC (hoặc ruby ​​hoặc java hoặc mật), những phương thức đó không thực sự riêng tư. Không có kiểm soát truy cập thực tế xung quanh họ. Bất kỳ ngôn ngữ nào cung cấp ngay cả một chút hướng nội cho phép các nhà phát triển có được các giá trị đó từ bên ngoài lớp nếu họ thực sự muốn.

Vì vậy, những gì chúng ta thực sự đang nói ở đây là một cách để xác định giao diện công khai chỉ trình bày chức năng mà chúng ta muốn và "ẩn" phần còn lại mà chúng ta coi là "riêng tư".

Cơ chế Swift để khai báo các giao diện là protocol và nó có thể được sử dụng cho mục đích này.

protocol MyClass {
  var publicProperty:Int {get set}
  func publicMethod(foo:String)->String
}

class MyClassImplementation : MyClass {
  var publicProperty:Int = 5
  var privateProperty:Int = 8

  func publicMethod(foo:String)->String{
    return privateMethod(foo)
  }

  func privateMethod(foo:String)->String{
    return "Hello \(foo)"
  }
}

Hãy nhớ rằng, các giao thức là loại hạng nhất và có thể được sử dụng bất cứ nơi nào một loại có thể. , khi được sử dụng theo cách này, họ chỉ để lộ các giao diện của riêng họ, không phải các giao diện thuộc loại thực hiện.

Do đó, miễn là bạn sử dụng MyClassthay vì MyClassImplementationtrong các loại tham số của mình, v.v ... tất cả chỉ nên hoạt động:

func breakingAndEntering(foo:MyClass)->String{
  return foo.privateMethod()
  //ERROR: 'MyClass' does not have a member named 'privateMethod'
}

Có một số trường hợp chuyển nhượng trực tiếp mà bạn phải rõ ràng với loại thay vì dựa vào Swift để suy luận, nhưng điều đó dường như không phải là một công cụ thỏa thuận:

var myClass:MyClass = MyClassImplementation()

Sử dụng các giao thức theo cách này là ngữ nghĩa, ngắn gọn hợp lý và trong mắt tôi trông rất giống với các Mức độ mở rộng mà chúng tôi đã sử dụng cho mục đích này trong ObjC.


1
Nếu các giao thức không cho phép chúng ta có một đối số mặc định, làm thế nào tôi có thể tạo một phương thức công khai với các tham số tùy chọn vẫn tuân thủ giao thức?
bdurao

Tôi không hiểu ý của bạn. Sau đây tạo ra một phương thức công khai với một tham số tùy chọn. Dường như không có vấn đề gì: gist.github.com/anonymous/17d8d2d25a78644046b6
jemmons 21/07/14

Vì một số lý do, tham số tùy chọn không hoạt động như dự án của tôi, đã thử một cái gì đó tương tự như ví dụ GitHub của bạn. Vì chúng ta không thể thiết lập một tham số mặc định trên một giao thức, tôi đã bị kẹt và cuối cùng đã đặt câu hỏi. Cảm ơn bạn đã cố gắng để giúp đỡ.
bdurao

Chúng ta đều biết rằng bất cứ điều gì cũng có thể hack. Chúng tôi chỉ cần một số thứ tự tại sao chúng tôi cần sửa đổi truy cập
canbax

14

Theo như tôi có thể nói, không có từ khóa 'công khai', 'riêng tư' hay 'được bảo vệ'. Điều này sẽ đề nghị mọi thứ là công khai.

Tuy nhiên, Apple có thể đang mong đợi mọi người sử dụng các giao thức của hệ thống viễn thông (được gọi là giao diện của phần còn lại của thế giới) và mẫu thiết kế nhà máy để ẩn chi tiết về loại triển khai.

Đây thường là một mẫu thiết kế tốt để sử dụng; vì nó cho phép bạn thay đổi hệ thống phân cấp lớp thực hiện , trong khi vẫn giữ nguyên hệ thống kiểu logic .


Điều này là tốt vì nó cũng làm giảm khớp nối và có thể làm cho thử nghiệm dễ dàng hơn.
Scroog1

4
Điều đó sẽ hoạt động tốt hơn nếu có một cách để ẩn lớp thực hiện của giao thức, nhưng dường như không có.
David Moles

Bất cứ ai cũng có thể cung cấp một ví dụ minh họa của mẫu này?
bloudermilk

Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

12

Sử dụng kết hợp các giao thức, bao đóng và các lớp lồng / bên trong, có thể sử dụng một cái gì đó dọc theo các dòng của mô hình mô-đun để ẩn thông tin trong Swift ngay bây giờ. Nó không siêu sạch hoặc đẹp để đọc nhưng nó hoạt động.

Thí dụ:

protocol HuhThing {
  var huh: Int { get set }
}

func HuhMaker() -> HuhThing {
   class InnerHuh: HuhThing {
    var innerVal: Int = 0
    var huh: Int {
      get {
        return mysteriousMath(innerVal)
      }

      set {
       innerVal = newValue / 2
      }
    }

    func mysteriousMath(number: Int) -> Int {
      return number * 3 + 2
    }
  }

  return InnerHuh()
}

HuhMaker()
var h = HuhMaker()

h.huh      // 2
h.huh = 32 
h.huh      // 50
h.huh = 39
h.huh      // 59

InternalVal và mystMath được ẩn ở đây từ bên ngoài sử dụng và cố gắng tìm đường vào đối tượng sẽ dẫn đến lỗi.

Tôi chỉ là một phần trong quá trình đọc tài liệu Swift của tôi vì vậy nếu có một lỗ hổng ở đây xin vui lòng chỉ ra, rất muốn biết.


ok, tôi cũng nghĩ về giải pháp này, nhưng giải thích cho tôi, tại sao tôi không thể tham gia với h.huh.innerVal?
Sam

Swift là loại an toàn và điều duy nhất mà thế giới bên ngoài biết về h là nó tuân thủ HuhThing. HuhThing không bao gồm bất kỳ thông tin nào về một thuộc tính được gọi là InternalVal và vì vậy cố gắng truy cập vào đó là một lỗi.
Dave Kapp

8
Vẫn có thể truy cập: Preflect(h)[0].1.value // 19
John Estropia

2
Rất vui được tìm thấy ở đó John - Tôi đã không nhận thức được phản ánh. Có vẻ để biến các đối tượng thành Tuples - có tài liệu chính thức nào về chức năng đó hoặc các công cụ lập trình siêu dữ liệu khác trong Swift không? Tôi đã xem qua hướng dẫn ngôn ngữ trên iBooks nhưng tôi không thấy nó.
Dave Kapp

1
@JohnEstropia Tôi không nghĩ là tính phản chiếu. Trong Java (một ngôn ngữ trưởng thành hơn), có các sửa đổi truy cập, nhưng chúng cũng không ngăn các thủ thuật phản chiếu.
11684

10

Kể từ Xcode 6 beta 4, Swift có các sửa đổi truy cập. Từ ghi chú phát hành:

Kiểm soát truy cập Swift có ba cấp độ truy cập:

  • các thực thể riêng tư chỉ có thể được truy cập từ trong tệp nguồn nơi chúng được xác định.
  • các thực thể nội bộ có thể được truy cập bất cứ nơi nào trong mục tiêu mà chúng được xác định.
  • các thực thể công cộng có thể được truy cập từ bất cứ đâu trong mục tiêu và từ bất kỳ bối cảnh nào khác nhập mô-đun của mục tiêu hiện tại.

Mặc định ngầm định là internal, vì vậy trong mục tiêu ứng dụng, bạn có thể tắt các công cụ sửa đổi truy cập trừ khi bạn muốn hạn chế hơn. Trong mục tiêu khung (ví dụ: nếu bạn nhúng khung để chia sẻ mã giữa ứng dụng và tiện ích mở rộng chế độ xem hoặc chia sẻ ngày hôm nay), hãy sử dụng publicđể chỉ định API bạn muốn hiển thị cho khách hàng của khung.


Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

6

Swift 3.0 cung cấp năm điều khiển truy cập khác nhau:

  1. mở
  2. công cộng
  3. nội bộ
  4. fileprivate
  5. riêng tư

Truy cập mở và truy cập công cộng cho phép các thực thể được sử dụng trong bất kỳ tệp nguồn nào từ mô đun xác định của chúng và cả trong một tệp nguồn từ một mô đun khác nhập mô đun xác định. Bạn thường sử dụng truy cập mở hoặc công khai khi chỉ định giao diện công cộng cho khung.

Truy cập nội bộ cho phép các thực thể được sử dụng trong bất kỳ tệp nguồn nào từ mô đun xác định của chúng, nhưng không phải trong bất kỳ tệp nguồn nào bên ngoài mô đun đó. Bạn thường sử dụng quyền truy cập nội bộ khi xác định cấu trúc bên trong của ứng dụng hoặc khung.

Truy cập tệp riêng tư hạn chế việc sử dụng thực thể đối với tệp nguồn xác định của chính nó. Sử dụng quyền truy cập riêng tư vào tệp để ẩn chi tiết triển khai của một phần chức năng cụ thể khi các chi tiết đó được sử dụng trong toàn bộ tệp.

Quyền truy cập riêng tư hạn chế việc sử dụng một thực thể trong khai báo kèm theo. Sử dụng quyền truy cập riêng để ẩn chi tiết triển khai của một chức năng cụ thể khi các chi tiết đó chỉ được sử dụng trong một khai báo.

Truy cập mở là cấp truy cập cao nhất (ít hạn chế nhất) và truy cập riêng là cấp truy cập thấp nhất (hạn chế nhất).

Cấp độ truy cập mặc định

Tất cả các thực thể trong mã của bạn (với một vài ngoại lệ cụ thể) có mức truy cập nội bộ mặc định nếu bạn không tự chỉ định cấp truy cập rõ ràng. Kết quả là, trong nhiều trường hợp, bạn không cần chỉ định cấp truy cập rõ ràng trong mã của mình.

Ghi chú phát hành về chủ đề:

Các lớp được khai báo là công khai không còn có thể được phân lớp bên ngoài mô đun xác định của chúng và các phương thức được khai báo là công khai không còn có thể bị ghi đè bên ngoài mô đun xác định của chúng. Để cho phép một lớp được phân lớp bên ngoài hoặc một phương thức được ghi đè bên ngoài, hãy khai báo chúng là mở, đây là một cấp truy cập mới ngoài công khai. Các lớp và phương thức Objective-C đã nhập bây giờ đều được nhập dưới dạng mở thay vì công khai. Các bài kiểm tra đơn vị nhập mô-đun bằng cách nhập @testable vẫn sẽ được phép phân lớp các lớp công khai hoặc nội bộ cũng như ghi đè các phương thức công khai hoặc nội bộ. (SE-0117)

Thêm thông tin & chi tiết: Ngôn ngữ lập trình Swift (Kiểm soát truy cập)


Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

4

Trong bản Beta 6, tài liệu nói rằng có ba công cụ sửa đổi truy cập khác nhau:

  • Công cộng
  • Nội bộ
  • Riêng tư

Và ba điều này áp dụng cho Class, Giao thức, chức năng và thuộc tính.

public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}

Để biết thêm, hãy kiểm tra Kiểm soát truy cập .


Nên có một công cụ sửa đổi được bảo vệ giúp dễ dàng tạo các lớp với độ bảo mật cao hơn.
Kumar C

Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

2

Bây giờ trong phiên bản beta 4, họ đã thêm các sửa đổi truy cập vào Swift.

từ Xcode 6 beta 4 ghi chú thực :

Kiểm soát truy cập Swift có ba cấp độ truy cập:

  • private các thực thể chỉ có thể được truy cập từ bên trong nguồn mà chúng được định nghĩa.
  • internal các thực thể có thể được truy cập ở bất cứ đâu trong mục tiêu mà chúng được định nghĩa.
  • public các thực thể có thể được truy cập từ bất cứ đâu trong mục tiêu và từ bất kỳ bối cảnh nào khác nhập mô-đun của mục tiêu hiện tại.

Theo mặc định, hầu hết các thực thể trong một nguồn đều có quyền truy cập nội bộ. Điều này cho phép các nhà phát triển ứng dụng phần lớn bỏ qua kiểm soát truy cập trong khi cho phép các nhà phát triển khung kiểm soát hoàn toàn đối với API của khung.


Bạn có thể gửi một liên kết đến điều này?
tuyết

Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

2

Các cơ chế kiểm soát truy cập như được giới thiệu trong Xcode 6 :

Swift cung cấp ba cấp độ truy cập khác nhau cho các thực thể trong mã của bạn. Các mức truy cập này liên quan đến tệp nguồn trong đó một thực thể được xác định và cũng liên quan đến mô-đun mà tệp nguồn thuộc về.

  • Truy cập công cộng cho phép các thực thể được sử dụng trong bất kỳ tệp nguồn nào từ mô đun xác định của chúng và cả trong tệp nguồn từ một mô đun khác nhập mô đun xác định. Bạn thường sử dụng quyền truy cập công cộng khi chỉ định giao diện chung cho khung.
  • Truy cập nội bộ cho phép các thực thể được sử dụng trong bất kỳ tệp nguồn nào từ mô đun xác định của chúng, nhưng không phải trong bất kỳ tệp nguồn nào bên ngoài mô đun đó. Bạn thường sử dụng quyền truy cập nội bộ khi xác định cấu trúc bên trong của ứng dụng hoặc khung.
  • Quyền truy cập riêng tư hạn chế việc sử dụng một thực thể đối với tệp nguồn xác định của chính nó. Sử dụng quyền truy cập riêng để ẩn chi tiết triển khai của một phần chức năng cụ thể.

Truy cập công cộng là cấp truy cập cao nhất (ít hạn chế nhất) và truy cập riêng là cấp truy cập thấp nhất (hoặc hạn chế nhất).

Mặc định accecss nó nội bộ , và như vậy không cần phải được chỉ định. Cũng lưu ý rằng trình xác định riêng không hoạt động ở cấp độ lớp, nhưng ở cấp độ tệp nguồn. Điều này có nghĩa là để có được các phần của một lớp thực sự riêng tư, bạn cần tách thành một tệp của riêng nó. Điều này cũng giới thiệu một số trường hợp thú vị liên quan đến thử nghiệm đơn vị ...

Một điểm khác với tôi, được nhận xét trong liên kết ở trên, là bạn không thể 'nâng cấp' cấp độ truy cập. Nếu bạn phân lớp một cái gì đó, bạn có thể hạn chế nó nhiều hơn, nhưng không phải là cách khác.

Bit cuối cùng này cũng ảnh hưởng đến các hàm, bộ dữ liệu và chắc chắn các thứ khác theo cách mà nếu một hàm sử dụng một lớp riêng thì không hợp lệ để có hàm bên trong hoặc công khai , vì chúng có thể không có quyền truy cập vào lớp riêng . Điều này dẫn đến một cảnh báo trình biên dịch và bạn cần phải xác định lại chức năng như một chức năng riêng tư .


Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

2

Swift 3 và 4 cũng mang lại rất nhiều thay đổi cho mức độ truy cập của các biến và phương thức. Swift 3 và 4 hiện có 4 cấp truy cập khác nhau, trong đó truy cập mở / công khai là cấp truy cập cao nhất (ít hạn chế nhất) và truy cập riêng là cấp truy cập thấp nhất (hạn chế nhất):

  • Các chức năng và thành viên riêng tư chỉ có thể được truy cập từ trong phạm vi của chính thực thể (struct, class, ') và các phần mở rộng của nó (trong Swift 3 cũng là các phần mở rộng bị hạn chế)
  • các chức năng fileprivate và các thành viên chỉ có thể được truy cập từ trong tệp nguồn nơi chúng được khai báo.
  • các chức năng và thành viên nội bộ (là mặc định, nếu bạn không thêm một từ khóa cấp độ truy cập) có thể được truy cập ở bất cứ đâu trong mục tiêu nơi chúng được xác định. Đó là lý do tại sao TestTarget không tự động truy cập vào tất cả các nguồn, chúng phải được đánh dấu là có thể truy cập trong trình kiểm tra tệp của xCode.
  • các chức năng và thành viên mở hoặc công khai có thể được truy cập từ bất kỳ đâu trong mục tiêu và từ bất kỳ bối cảnh nào khác nhập mô-đun của mục tiêu hiện tại.

Hấp dẫn:

Thay vì đánh dấu mỗi phương thức hoặc thành viên là "riêng tư", bạn có thể bao gồm một số phương thức (ví dụ: thường là các hàm trợ giúp) trong phần mở rộng của lớp / struct và đánh dấu toàn bộ phần mở rộng là "Riêng tư".

class foo { }

private extension foo {
    func somePrivateHelperFunction01() { }
    func somePrivateHelperFunction02() { }
    func somePrivateHelperFunction03() { }
}

Đây có thể là một ý tưởng tốt, để có được mã duy trì tốt hơn. Và bạn có thể dễ dàng chuyển đổi (ví dụ để kiểm tra đơn vị) sang không riêng tư chỉ bằng cách thay đổi một từ.

Tài liệu của Apple


Chà, câu trả lời này là hợp lệ trong (các) phiên bản Swift trước, có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

2

Dành cho Swift 1-3:

Không, nó không thể. Không có bất kỳ phương thức và biến riêng tư / được bảo vệ nào cả.

Mọi thứ đều công khai.

Cập nhật Kể từ Swift 4, có thể thấy các câu trả lời khác trong chuỗi này


1
Nhận xét này là chính xác cho hạt giống hiện tại.
Jesper

2
Đối với hạt giống hiện tại. Nó sẽ xuất hiện trong tương lai .
Jesper

1
"Công khai" / "được bảo vệ" / "riêng tư" hiện không tồn tại, nhưng bạn có thể ẩn mọi thứ bằng cách sử dụng các bao đóng, giao thức và các lớp bên trong - điều này làm cho nó giống như mô hình mô-đun được sử dụng phổ biến trong JavaScript. Xin vui lòng xem mã mẫu của tôi trên trả lời của tôi ở đây để biết ví dụ về cách làm điều này. Nếu tôi nhầm về cách thức hoạt động và ví dụ của tôi không chính xác, vui lòng chỉ ra rằng tôi vẫn đang học. :)
Dave Kapp

Có vẻ như nó không còn giá trị nữa :) vui lòng kiểm tra câu trả lời của tôi .
Ahmad F

1

Một trong các tùy chọn bạn có thể sử dụng là kết hợp việc tạo cá thể vào một hàm và cung cấp các getters và setters thích hợp trong một hàm tạo:

class Counter {
    let inc: () -> Int
    let dec: () -> Int

    init(start: Int) {
        var n = start

        inc = { ++n }
        dec = { --n }
    }
}


let c = Counter(start: 10)

c.inc()  // 11
c.inc()  // 12
c.dec()  // 11

0

Các ngữ pháp ngôn ngữ không có từ khóa 'công cộng', 'tư nhân' hoặc 'bảo vệ'. Điều này sẽ đề nghị mọi thứ là công khai. Tất nhiên, có thể có một số phương pháp khác để chỉ định công cụ sửa đổi truy cập mà không có các từ khóa đó nhưng tôi không thể tìm thấy nó trong tài liệu tham khảo ngôn ngữ.


0

Hy vọng sẽ tiết kiệm thời gian cho những ai muốn một cái gì đó giống với các phương pháp được bảo vệ:

Theo các câu trả lời khác, swift hiện cung cấp công cụ sửa đổi 'riêng tư' - được xác định là khôn ngoan tệp chứ không phải là thông minh lớp, chẳng hạn như trong Java hoặc C #. Điều này có nghĩa là nếu bạn muốn các phương thức được bảo vệ, bạn có thể thực hiện nó với các phương thức riêng tư nhanh chóng nếu chúng nằm trong cùng một tệp

  1. Tạo một lớp cơ sở để giữ các phương thức 'được bảo vệ' (thực sự là riêng tư)
  2. Phân lớp lớp này để sử dụng các phương thức tương tự
  3. Trong các tệp khác, bạn không thể truy cập các phương thức lớp cơ sở, ngay cả khi bạn phân lớp

ví dụ: tệp 1:

class BaseClass {
    private func protectedMethod() {

    }
}

class SubClass : BaseClass {
    func publicMethod() {
        self.protectedMethod()  //this is ok as they are in same file
    }
}

Tệp 2:

func test() {
    var a = BaseClass()
    a.protectedMethod() //ERROR


    var b = SubClass()
    b.protectedMethod() //ERROR
}

class SubClass2 : BaseClass {
    func publicMethod() {
        self.protectedMethod() //ERROR
    }

}



-2

cho đến swift 2.0 chỉ có ba cấp truy cập [Công khai, nội bộ, riêng tư] nhưng trong swift 3.0 apple đã thêm hai cấp truy cập mới là [Mở, loại tệp] vì vậy bây giờ trong swift 3.0 có 5 cấp truy cập Ở đây tôi muốn xóa vai trò này của hai cấp độ truy cập 1. Mở này: tương tự như Công khai nhưng điểm khác biệt duy nhất là Công chúng có thể truy cập lớp con và ghi đè và Cấp truy cập mở không thể truy cập rằng hình ảnh này được lấy từ trang web Trung bình và điều này mô tả sự khác biệt giữa truy cập mở và công cộng

Bây giờ đến cấp truy cập mới thứ hai 2. filetype là phiên bản lớn hơn của cấp độ truy cập riêng tư hoặc ít hơn so với bên trong FileType có thể truy cập phần mở rộng của [class, struct, enum] và private không thể truy cập vào phần mở rộng của mã mà nó chỉ có thể truy cập phạm vi từ vựng hình ảnh này được lấy từ trang web Trung bình và điều này mô tả sự khác biệt giữa cấp độ truy cập tệp và Loại riêng tư

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.