Thành viên sơ thẩm không thể được sử dụng trên loại


138

Tôi có lớp sau:

class ReportView: NSView {  
    var categoriesPerPage = [[Int]]()
    var numPages: Int = { return categoriesPerPage.count }
}

Quá trình biên dịch thất bại với thông báo:

Thành viên sơ thẩm 'chuyên mụcPerPage' không thể được sử dụng trên loại 'Báo cáo'

Điều đó có nghĩa là gì?


12
Đoán rằng bạn sẽ khai báo một tài sản được tính toán numPagesthay vì đóng cửa xóa dấu bằng:var numPages: Int { return categoriesPerPage.count }
vadian

1
Nó có thể được giải thích kỹ hơn chính xác ý nghĩa của thông báo lỗi này không? Tôi đang nhìn thấy nó trong một bối cảnh hoàn toàn khác.
William Entriken

2
Khi bạn khai báo một khối trong phạm vi lớp, như trên, bạn bị giới hạn ở những gì có sẵn trong loại. Bạn không có quyền truy cập vào bất kỳ thành viên thể hiện.
Aderstedt

Lưu ý: Thông báo lỗi tương tự như thông báo lỗi bạn nhận được khi cố gắng tạo biến lười biếng nhưng quên một trong các yêu cầu . Trong trường hợp của bạn, bạn không muốn một biến lười biếng categoriesPerPageđược định nghĩa là varthay vì let.
Nhận thức

1
Xóa = từ: var numPages: Int =
andrewz

Câu trả lời:


131

Bạn chỉ có lỗi cú pháp khi nói = {return self.someValue}. Điều =không cần thiết.

Sử dụng :

var numPages: Int {
    get{
        return categoriesPerPage.count
    }

}

nếu bạn muốn chỉ có bạn có thể viết

var numPages: Int {
     return categoriesPerPage.count
}

với cách đầu tiên, bạn cũng có thể thêm người quan sát là set willSet&didSet

var numPages: Int {
    get{
        return categoriesPerPage.count
    }
    set(v){
       self.categoriesPerPage = v
    }
}

cho phép sử dụng = operatornhư một setter

myObject.numPages = 5

1
Rất tiếc, tôi đã bỏ lỡ dấu bằng. Cảm ơn.
Aderstedt

Bạn đang nói rằng bạn sẽ khởi tạo categoriesPerPage, đó là mảng 2 mờ với vInt?
Dan

@Dan Your'e đúng, Ví dụ chỉ là để chứng minh setví dụ, tất nhiên bạn không thể gán intvào[int]
Daniel Krom

Thực hiện điều này một triệu lần và vẫn bỏ lỡ dấu phụ = dấu hiệu :)
Alexandre G

bạn không cần gia đình dấu chấm phẩy
Peter Schorn

51

Đối với bất kỳ ai khác vấp phải điều này, hãy đảm bảo rằng bạn không cố gắng sửa đổi lớp thay vì thể hiện! (trừ khi bạn đã khai báo biến là tĩnh)

ví dụ.

MyClass.variable = 'Foo' // WRONG! - Instance member 'variable' cannot be used on type 'MyClass'

instanceOfMyClass.variable = 'Foo' // Right!

5
Đây là sự khác biệt giữa staticbiến và instancebiến, MyClass.variablelà hợp lệ nếu bạn khai báo nó là biến tĩnh (được chia sẻ giữa tất cả các trường hợp)
Daniel Krom

Đây là vấn đề của tôi. Tôi thấy thật kỳ quặc khi XCode quyết định đặt lớp đầu tiên trong các tùy chọn tự động hoàn thành trước một cá thể có tên tương tự khi bối cảnh dường như chỉ đến tôi chắc chắn sử dụng cá thể chứ không phải chính lớp đó. Và trong trường hợp cá thể của bạn chỉ khác nhau theo từng trường hợp, có thể khó nhận thấy bạn đã chọn lớp thay vì thể hiện mà bạn muốn nói. Cảm ơn!
LeftOnTheMoon

19

Có nghĩa là bạn có một biến đối tượng (var chỉ hiển thị / có thể truy cập khi bạn có một thể hiện của lớp đó) và bạn đang cố gắng sử dụng nó trong ngữ cảnh của một phạm vi tĩnh (phương thức lớp).

Bạn có thể biến biến cá thể của mình thành một biến lớp bằng cách thêm thuộc tính static / class.

Bạn khởi tạo một thể hiện của lớp của bạn và gọi phương thức cá thể trên biến đó.


Trong trường hợp của tôi, tôi đã cố gắng sử dụng một biến đối tượng trong khối hoàn thành được gọi sau khi một thể hiện của một lớp khác đã được khởi tạo. Tất nhiên, một init là một hàm lớp và khai báo biến thể hiện là tĩnh đã giải quyết vấn đề.
Reinhard Männer

8

Một ví dụ khác là, bạn có lớp như:

@obc class Album: NSObject {
    let name:String
    let singer:Singer
    let artwork:URL
    let playingSong:Song


    // ...

    class func getCurrentlyPlayingSongLyric(duration: Int = 0) -> String {
        // ...
       return playingSong.lyric
    }
}

bạn cũng sẽ nhận được cùng một loại lỗi như:

instance member x cannot be used on type x. 

Đó là bởi vì bạn gán phương thức của mình với từ khóa "class" (làm cho phương thức của bạn trở thành phương thức kiểu) và sử dụng như:

Album.getCurrentlyPlayingSongLyric(duration: 5)

nhưng ai đã đặt biến playingSong trước đây? Đồng ý. Bạn không nên sử dụng từ khóa lớp cho trường hợp đó:

 // ...

 func getCurrentlyPlayingSongLyric(duration: Int = 0) -> String {
        // ...
       return playingSong.lyric
 }

 // ...

Bây giờ bạn được tự do đi.


7

Đôi khi Xcode khi ghi đè các phương thức thêm class functhay vì chỉ func. Sau đó, trong phương thức tĩnh, bạn không thể thấy các thuộc tính thể hiện. Nó rất dễ dàng để bỏ qua nó. Đó là trường hợp của tôi.

nhập mô tả hình ảnh ở đây


Ah cảm ơn bạn! Đã dành một thời gian dài để tìm hiểu lý do tại sao tôi không nhận được bất kỳ đề xuất tự động hoàn thành thành viên nào trong Xcode. Đây có vẻ như là một lỗi, tôi sẽ gửi một radar với Apple
Apoorv Khatreja

3

Vấn đề ban đầu của bạn là:

class ReportView: NSView {
  var categoriesPerPage = [[Int]]()
  var numPages: Int = { return categoriesPerPage.count }
}

Thành viên sơ thẩm 'chuyên mụcPerPage' không thể được sử dụng trên loại 'Báo cáo'

bài viết trước chỉ ra một cách chính xác, nếu bạn muốn một thuộc tính được tính toán , =dấu hiệu bị xóa.

Khả năng bổ sung cho lỗi:

Nếu mục đích của bạn là "Đặt giá trị thuộc tính mặc định bằng cách đóng hoặc chức năng" , bạn cũng chỉ cần thay đổi một chút. (Lưu ý: ví dụ này rõ ràng không có ý định làm điều đó)

class ReportView: NSView {
  var categoriesPerPage = [[Int]]()
  var numPages: Int = { return categoriesPerPage.count }()
}

Thay vì loại bỏ =, chúng tôi thêm() vào để biểu thị một đóng cửa khởi tạo mặc định. (Điều này có thể hữu ích khi khởi tạo mã UI, để giữ tất cả ở một nơi.)

Tuy nhiên, lỗi chính xác tương tự xảy ra:

Thành viên sơ thẩm 'chuyên mụcPerPage' không thể được sử dụng trên loại 'Báo cáo'

Vấn đề là cố gắng khởi tạo một thuộc tính với giá trị của một thuộc tính khác. Một giải pháp là tạo bộ khởi tạo lazy. Nó sẽ không được thực thi cho đến khi giá trị được truy cập.

class ReportView: NSView {
  var categoriesPerPage = [[Int]]()
  lazy var numPages: Int = { return categoriesPerPage.count }()
}

bây giờ trình biên dịch là hạnh phúc!


0

Tôi tiếp tục nhận được cùng một cảm hứng lỗi khi thực hiện biến static. Giải pháp: Clean Build, Clean Derogen Data, Khởi động lại Xcode. Hoặc phím tắt Cmd + Shift + Alt + K

UserNotificationCenterWrapper.delegate = self

public static var delegate: UNUserNotificationCenterDelegate? {
        get {
            return UNUserNotificationCenter.current().delegate
        }
        set {
            UNUserNotificationCenter.current().delegate = newValue
        }
    }

0

Chỉ trong trường hợp ai đó thực sự cần đóng cửa như vậy, nó có thể được thực hiện theo cách sau:

var categoriesPerPage = [[Int]]()
var numPagesClosure: ()->Int {
    return {
        return self.categoriesPerPage.count
    }
}
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.