10

I have an NSFormatter in Swift, which is attached to an NSTextField. It prevents illegal characters from being entered, but when I try to access the value of the next field it gives a nil value.

Below is the class:

class PSEntryNameFormatter : NSFormatter {
    override func stringForObjectValue(obj: AnyObject?) -> String? {

        if obj == nil {
            println("stringForObjectValue: obj is nil, returning nil")
            return nil
        }
        if let o = obj as? String {
                println("stringForObjectValue:  obj is string, returning \(o)")
                return o
            }

        println("stringForObjectValue: obj is not string, returning nil")
        return nil
    }

    override func getObjectValue(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>, forString string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
        println("getObjectValue: \(string)")
        let obj = string
        return true
    }

    override func isPartialStringValid(partialString: String?, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>) -> Bool {
        if let s = partialString {
            var illegals : String = join("",s.componentsSeparatedByCharactersInSet(PSEntryNameFormatterCharacterSet))
            var goods = s.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: illegals))
            let newString : NSString = join("", goods)

            if String(newString) == s {
                println("isPartialStringValid: partial string ok")
                return true
            }
        }

        println("isPartialStringValid: partial string bad")
        return false
    }
}

And here is how I try to access:

func control(control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
    println("Text should end editing")
    if (control == nameTextField) {
        var name = nameTextField.objectValue as String
        setObjectName(name)
    }
    return true
}

For debugging I add the println statements, and here is what happens when the textfield is set to 'Template' and then I delete two characters:

stringForObjectValue:  obj is string, returning Template
stringForObjectValue:  obj is string, returning Template
isPartialStringValid: partial string ok
getObjectValue: Templat
isPartialStringValid: partial string ok
getObjectValue: Templa

Then I press enter:

getObjectValue: Templa
Text should end editing 
getObjectValue: Templa
stringForObjectValue: obj is nil, returning nil
getObjectValue:
stringForObjectValue: obj is nil, returning nil
stringForObjectValue: obj is nil, returning nil
fatal error: unexpectedly found nil while unwrapping an Optional value

And then it crashes on the line when I cast to string. Obviously I can prevent the crash, but first I want to find out why it is returning nil. Any help very much appreciated!

4

2 回答 2

14

问题出在您的 getObjectValue 函数中。

您应该以这种方式分配值:

obj.memory = string

代替

let obj = string
于 2015-01-09T20:47:50.407 回答
0

我有一个类似的问题并得到了部分修复:

override func stringForObjectValue(obj: AnyObject) -> String? {
  if let desc = obj.description {
    println("sFO=\(obj)")
  } else {
    println("sFO=nil")
  }
  return obj.description
}

但是每次我跳出该字段时,它的内容都会再次设置为零。仍然坚持这一点。我对模拟 OC 代码没有任何问题。

于 2014-11-01T18:51:20.297 回答