问题
I have an array of numbers that have been generated randomly and I am then trying to query Firebase for a question that is equal to the value at index [0] in the array of chosen numbers. The problem at the moment is that I get an error Cannot subscript a value of type '[UInt32]'
. P.S. I am not extremly experienced in swift so exact code solutions would be very apreciated! I have also attached my firebase structure...
import UIKit
import Firebase
class QuestionViewController: UIViewController {
let ref = Firebase(url: "https://123test123.firebaseio.com/questions")
override func viewDidLoad() {
super.viewDidLoad()
// An empty array to hold the selected numbers
var selectedNumbers: [UInt32] = []
// A range of acceptable numbers
let randomNumberRange = 1...10
// How many numbers are needed?
let randomNumbersToChoose = 10
// Crash if asking for more numbers than are available in the range
assert(randomNumberRange.count >= randomNumbersToChoose, "Must have enough numbers to choose from!")
// Repeat this loop until all enough numbers have been selected
while selectedNumbers.count < randomNumbersToChoose {
// Pick a random number within the allowed range
let selectedNumber = arc4random_uniform(UInt32(randomNumberRange.endIndex - randomNumberRange.startIndex)) + UInt32(randomNumberRange.startIndex)
// If it's not already in the selected array, add it
if (selectedNumbers.indexOf(selectedNumber) == nil) {
selectedNumbers.append(selectedNumber)
}
}
// Print the result
print(selectedNumbers)
print(selectedNumbers)
let selectedNumberIndex: UInt32 = 2
ref.queryOrderedByChild("value").queryEqualToValue(selectedNumbers[0])
.observeEventType(.ChildAdded, withBlock: {
snapshot in
//Do something with the question
print(snapshot.key)
print(snapshot.value.valueForKey("question"))
})
}
@IBAction func truepressed(sender: AnyObject) {
}
@IBAction func falsePressed(sender: AnyObject) {
}
}
JSON data:
{
"question1" : {
"answer" : "Nohghpe",
"question" : "Do you know swift",
"value" : 1
},
"question10" : {
"answer" : "A fdsbit",
"question" : "Do you kndfggow firebase",
"value" : 10
},
"question2" : {
"answer" : "A bfhit",
"question" : "Dodhfg you know firebase",
"value" : 2
},
"question3" : {
"answer" : "A bsdit",
"question" : "Do you know firebsgdfase",
"value" : 3
},
"question4" : {
"answer" : "A vcxbit",
"question" : "Do yosgfdu know firebase",
"value" : 4
},
"question5" : {
"answer" : "A bivcxt",
"question" : "Do you kfghnow firebase",
"value" : 5
},
"question6" : {
"answer" : "A bxcvit",
"question" : "Do you know fnhirebase",
"value" : 6
},
"question7" : {
"answer" : "A bivxct",
"question" : "Do you sgdfknow firebase",
"value" : 7
},
"question8" : {
"answer" : "A bivcxt",
"question" : "Do you knsfdow firebase",
"value" : 8
},
"question9" : {
"answer" : "A bdsfit",
"question" : "Do you kdfgnow ffsdirebase",
"value" : 9
}
}
回答1:
This is a typical situation of the Swift compiler obscuring the real error behind another one. The .queryEqualToValue(..) method expects an argument of type AnyObject
; which can hold only reference (class) types, whereas UInt32
is a value type.
Another subject of confusion could be that we're generally used to the fact that AnyObject
types can, seemingly, hold Int
types, when in fact such assignments implicitly converts the Swift native Int
value type to the Foundation __NSCFNumber
reference type. This implicit conversion is, however, not available for UInt32
type.
var a : AnyObject?
let foo : [Int] = [1, 2, 3]
let bar : [UInt32] = [1, 2, 3]
/* OK: Int -> [implicitly] -> __NSCFNumber */
a = foo[0]
print(a!.dynamicType) // __NSCFNumber
/* Not OK */
a = bar[0]
/* error: cannot subscript a value of type '[UInt32]' a = bar[0] */
Hence, you could solve this issue by:
Letting
selectedNumbers
be an array 0fInt
, rather thanUInt32
(and modify the affected parts of your code accordingly).Perform a type conversion from
UInt32
toInt
in your call to.queryEqualToValue(..)
. E.g., in the example above:a = Int(bar[0])
Just take care that for 32-bit systems (e.g. iPhone 5), half the upper range of numbers representable by
UInt32
type cannot be represented byInt
type, since on 32-bit system,Int
corresponds toInt32
.INT32_MAX // 2147483647 UINT32_MAX // 4294967295
From a quick glance at your code, however, it doesn't seem as if this should be an issue here, as the elements of
selectedNumbers
will not contain the larger numbers representable byUInt32
(and, for 64-bit systems: OK, asInt
corresponds toInt64
). If choosing this option, you should, however, for good practice, assert prior to conversion that theUInt32
value can be represented by theInt
type on the systems intended to run your application.
来源:https://stackoverflow.com/questions/35668775/cannot-subscript-a-value-of-type-uint32