可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I understand, this particular error was already posted here and there and the code is somewhat basic, but I myself still unable to figure this one out & I need advice.
The thing is when I add the first two lines of code provided on parse.com for saving objects
var gameScore = PFObject(className:"GameScore")
gameScore["score"] = 1337
I get the following error for the second line:
'PFObject' does not have a member named 'subscript'
I'm on Xcode 6.3 beta 2.
All required libraries are linked with binary, <Parse/Parse.h>
imported via BridgeHeader.
What syntax should I use?
回答1:
This is happening due to the 1.6.4 version of the parse sdk which added Objective-C Nullability Annotations to the framework. In particular the file Parse/PFObject.h
defines:
- (PF_NULLABLE_S id)objectForKeyedSubscript:(NSString *)key;
which is causing the Swift compile error. Removing the PF_NULLABLE_S
fixes the problem.
On the other hand it seems correct that an object for a keyed subscript might be nil
, so I suspect this is a Swift bug...
回答2:
The problem seems to be the changed method signature, as kashif suggested. Swift doesn't seem to be able to bridge to the Objective-C method because the signature no longer matches the subscript method names.
Workaround 1
You can work around this without modifying the framework by calling the subscript method directly, instead of using the []
operator:
Instead of using the instruction below for getting the value of a particular key:
let str = user["key-name"] as? Bool
Please use the following instruction:
let str = user.objectForKey("key-name") as? Bool
and
Instead of using the instruction below for setting the value of a particular key:
user["key-name"] = "Bla bla"
Please use the following instruction:
user.setObject("Bla bla", forKey: "key-name")
Workaround 2
Another solution is to add an extension on PFObject that implements the subscript
member and calls setValue:forKey:
:
extension PFObject {
subscript(index: String) -> AnyObject? {
get {
return self.valueForKey(index)
}
set(newValue) {
if let newValue: AnyObject = newValue {
self.setValue(newValue, forKey: index)
}
}
}
}
Note that this second workaround isn't entirely safe, since I'm not sure how Parse actually implements the subscript methods (maybe they do more than just calling setValue:forKey
- it has worked in my simple test cases, so it seems like a valid workaround until this is fixed in Parse/Swift.
回答3:
I've successfully run your exact code.
First, make sure you are indeed saving the object in the background, after you set the new value:
gameScore.save()
I would double check for misspellings in the class name and subclass; if they are incorrect, it will not work.
If that's not the problem, verify in Parse that the "score" subclass is set to be a number. If you accidentally set it to be a string, setting it as an integer will not work.
If these suggestions have not hit the solution, then I'm not sure what the problem is. Hope I helped.
回答4:
I encountered a similar error with Parse 1.6.4 and 1.6.5 in the PFConstants.h header file with method parameters.
Xcode 6.3 beta 4 has a note in the "New in..." section regarding nullability operators.
Moving the nullability operator between the pointer operator and the variable name seems to comply/compile.
Changing:
PF_NULLABLE_S NSError *error
to:
NSError * PF_NULLABLE_S error
(i.e., NSError* __nullable error)
... resolved the compiler error.
This also worked for block parameters defined with id. So...
PF_NULLABLE_S id object
becomes:
id PF_NULLABLE_S object
In the above case, perhaps:
- (id PF_NULLABLE_S)objectForKeyedSubscript:(NSString *)key;
I.e., the nullability operator is after the pointer type.
回答5:
I know its been a while but I encountered a similar problem when I was starting my first Parse application with SDK version 1.9.1.
The Quickstart guide had the code below as an example as to how to save values:
let testObject = PFObject(className: "TestObject")
testObject["foo"] = "bar"
testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
println("Object has been saved.")
}
But, the line testObject["foo"] = "bar"
returned the error 'PFObject' does not have a member named 'subscript'
. I was able to work around the problem by changing the line to testObject.setValue("bar", forKey: "foo")
. (As suggested by a tutorial video on YouTube: https://www.youtube.com/watch?v=Q6kTw_cK3zY)