ไม่สามารถใช้สมาชิกอินสแตนซ์ในประเภท


142

ฉันมีคลาสต่อไปนี้:

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

การคอมไพล์ล้มเหลวด้วยข้อความ:

ไม่สามารถใช้สมาชิกอินสแตนซ์ 'categoryPerPage' กับประเภท 'ReportView'

สิ่งนี้หมายความว่า?


12
เดาว่าคุณกำลังจะประกาศคุณสมบัติที่คำนวณได้numPagesแทนที่จะเป็นการปิดลบเครื่องหมายเท่ากับ:var numPages: Int { return categoriesPerPage.count }
vadian

1
โปรดอธิบายให้ละเอียดมากขึ้นได้ไหมว่าข้อความแสดงข้อผิดพลาดนี้หมายถึงอะไร ฉันเห็นมันในบริบทที่แตกต่างไปจากเดิมอย่างสิ้นเชิง
William Entriken

2
เมื่อคุณประกาศบล็อกในขอบเขตคลาสเช่นข้างต้นคุณจะ จำกัด เฉพาะสิ่งที่มีอยู่ในประเภท คุณไม่มีสิทธิ์เข้าถึงสมาชิกอินสแตนซ์ใด ๆ
Aderstedt

หมายเหตุ: ข้อความแสดงข้อผิดพลาดคล้ายกับที่คุณได้รับเมื่อพยายามสร้างตัวแปร lazy แต่ลืมข้อกำหนดข้อใดข้อหนึ่ง ในกรณีของคุณคุณไม่ต้องการตัวแปรขี้เกียจนับตั้งแต่categoriesPerPageถูกกำหนดให้เป็นแทนvar let
Senseful

1
Remove = from: var numPages: Int =
andrewz

คำตอบ:


135

= {return self.someValue}คุณเพียงแค่ต้องไวยากรณ์ผิดพลาดเมื่อพูด =ไม่จำเป็นต้อง

ใช้:

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

}

ถ้าคุณต้องการเพียงคุณสามารถเขียน

var numPages: Int {
     return categoriesPerPage.count
}

ด้วยวิธีแรกคุณยังสามารถเพิ่มผู้สังเกตการณ์เป็นset willSet&didSet

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

อนุญาตให้ใช้= operatorเป็นตัวตั้งค่า

myObject.numPages = 5

1
อ๊ะฉันพลาดเครื่องหมายเท่ากับ ขอบคุณ.
Aderstedt

คุณกำลังบอกว่าคุณกำลังจะเริ่มต้นcategoriesPerPageอาร์เรย์ 2-dim vซึ่งเป็น Int?
แดน

@Dan Your'e ถูกต้องตัวอย่างเป็นเพียงsetตัวอย่างที่แสดงให้เห็นว่าคุณไม่สามารถกำหนดให้intเป็น[int]
Daniel Krom

ทำสิ่งนี้เป็นล้านครั้งแล้วและยังพลาดเครื่องหมาย = พิเศษ :)
Alexandre G

คุณไม่จำเป็นต้องใช้อัฒภาค fam
Peter Schorn

54

สำหรับใครก็ตามที่สะดุดกับสิ่งนี้ให้แน่ใจว่าคุณไม่ได้พยายามปรับเปลี่ยนคลาสแทนที่จะเป็นอินสแตนซ์! (เว้นแต่คุณจะประกาศตัวแปรเป็นแบบคงที่)

เช่น.

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

instanceOfMyClass.variable = 'Foo' // Right!

5
นี่คือความแตกต่างระหว่างstaticตัวแปรและinstanceตัวแปรMyClass.variableใช้ได้ถ้าคุณจะประกาศว่าเป็นตัวแปรคงที่ (ใช้ร่วมกันระหว่างอินสแตนซ์ทั้งหมด)
Daniel Krom

นี่คือปัญหาของฉัน ฉันคิดว่ามันแปลกเมื่อ XCode ตัดสินใจให้คลาสเป็นอันดับแรกในตัวเลือกการเติมข้อความอัตโนมัติก่อนอินสแตนซ์ที่มีชื่อคล้ายกันเมื่อบริบทดูเหมือนจะชี้ให้ฉันเห็นว่าใช้อินสแตนซ์มากกว่าคลาสเอง และในกรณีที่อินสแตนซ์ของคุณแตกต่างกันไปตามแต่ละกรณีอาจสังเกตได้ยากว่าคุณเลือกคลาสแทนที่จะเป็นอินสแตนซ์ที่คุณต้องการ ขอบคุณ!
LeftOnTheMoon

26

บางครั้ง Xcode เมื่อวิธีการแทนที่เพิ่มแทนเพียงclass func funcจากนั้นในวิธีการคงที่คุณจะไม่เห็นคุณสมบัติของอินสแตนซ์ เป็นเรื่องง่ายมากที่จะมองข้ามมันไป นั่นคือกรณีของฉัน

ป้อนคำอธิบายภาพที่นี่


1
อ๊ะขอบคุณ! ใช้เวลานานในการหาสาเหตุที่ฉันไม่ได้รับคำแนะนำในการเติมข้อความอัตโนมัติของสมาชิกอินสแตนซ์ใน Xcode ดูเหมือนว่าจะเป็นข้อบกพร่องฉันจะยื่นเรดาร์กับ Apple 👍🏽
Apoorv Khatreja

การเติมข้อความอัตโนมัติก็ทำให้ฉันเสียหายเช่นกัน นี่ดูเหมือนข้อบกพร่องสำหรับฉันด้วย
Deitsch

20

เป็นการบอกว่าคุณมีตัวแปรอินสแตนซ์ (ตัวแปรจะมองเห็น / เข้าถึงได้ก็ต่อเมื่อคุณมีอินสแตนซ์ของคลาสนั้น) และคุณกำลังพยายามใช้มันในบริบทของขอบเขตแบบคงที่ (วิธีคลาส)

คุณสามารถทำให้ตัวแปรอินสแตนซ์ของคุณเป็นตัวแปรคลาสได้โดยเพิ่มแอตทริบิวต์แบบคงที่ / คลาส

คุณสร้างอินสแตนซ์อินสแตนซ์ของคลาสของคุณและเรียกใช้วิธีการอินสแตนซ์กับตัวแปรนั้น


ในกรณีของฉันฉันพยายามใช้ตัวแปรอินสแตนซ์ในบล็อกการเสร็จสิ้นที่เรียกว่าหลังจากเริ่มต้นอินสแตนซ์ของคลาสอื่นแล้ว แน่นอนว่า init เป็นฟังก์ชันคลาสและการประกาศตัวแปรอินสแตนซ์เป็นแบบคงที่ช่วยแก้ปัญหาได้
Reinhard Männer

9

อีกตัวอย่างหนึ่งคือคุณมีคลาสเช่น:

@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
    }
}

คุณจะได้รับข้อผิดพลาดประเภทเดียวกันเช่น:

instance member x cannot be used on type x. 

เป็นเพราะคุณกำหนด method ของคุณด้วยคีย์เวิร์ด "class" (ซึ่งทำให้ method ของคุณเป็น method type) และใช้ like:

Album.getCurrentlyPlayingSongLyric(duration: 5)

แต่ใครเป็นคนตั้งค่าตัวแปร playSong ก่อนหน้า? ตกลง. คุณไม่ควรใช้คีย์เวิร์ดระดับสำหรับกรณีนั้น:

 // ...

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

 // ...

ตอนนี้คุณมีอิสระที่จะไป


3

ปัญหาเริ่มต้นของคุณคือ:

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

ไม่สามารถใช้สมาชิกอินสแตนซ์ 'categoryPerPage' กับประเภท 'ReportView'

บทความก่อนหน้านี้ได้อย่างถูกต้องชี้ให้เห็นถ้าคุณต้องการคุณสมบัติการคำนวณที่=ป้ายเป็นหลง

ความเป็นไปได้เพิ่มเติมสำหรับข้อผิดพลาด:

หากเจตนาของคุณคือ"การตั้งค่าคุณสมบัติเริ่มต้นด้วยการปิดหรือฟังก์ชั่น"คุณจะต้องเปลี่ยนแปลงเพียงเล็กน้อยเช่นกัน (หมายเหตุ: เห็นได้ชัดว่าตัวอย่างนี้ไม่ได้ตั้งใจทำเช่นนั้น)

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

แทนที่จะลบ=เราเพิ่ม()เพื่อแสดงถึงการปิดการเริ่มต้นเริ่มต้น (สิ่งนี้จะมีประโยชน์เมื่อเริ่มต้นโค้ด UI เพื่อเก็บไว้ในที่เดียว)

อย่างไรก็ตามข้อผิดพลาดเดียวกันเกิดขึ้น:

ไม่สามารถใช้สมาชิกอินสแตนซ์ 'categoryPerPage' กับประเภท 'ReportView'

ปัญหากำลังพยายามเริ่มต้นคุณสมบัติหนึ่งด้วยค่าของอีกคุณสมบัติหนึ่ง lazyทางออกหนึ่งที่จะทำให้การเริ่มต้น จะไม่ถูกดำเนินการจนกว่าจะเข้าถึงค่า

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

ตอนนี้คอมไพเลอร์มีความสุข!


0

staticผมเก็บไว้ทั้งๆที่ได้รับข้อผิดพลาดเดียวกันในการทำตัวแปร วิธีแก้ไข: Clean Build, Clean ข้อมูลที่ได้มา, รีสตาร์ท Xcode หรือทางลัด Cmd + Shift + Alt + K

UserNotificationCenterWrapper.delegate = self

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

0

ในกรณีที่มีคนต้องการปิดบัญชีแบบนั้นจริงๆสามารถทำได้ด้วยวิธีต่อไปนี้:

var categoriesPerPage = [[Int]]()
var numPagesClosure: ()->Int {
    return {
        return self.categoriesPerPage.count
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.