在编写Master-Detail应用程序时,我在Swift中遇到了一个奇怪的行为。
这是场景:
这是一个简单的Task Manager应用程序。我有两个文本控件(TASKNAME,TaskDescription在TaskDetailView),并具有相同的名称,但在lowerCamelCase(两个字符串变量TASKNAME,taskDescription)在TaskDetailViewController声明。
@IBOutlet var TaskName:UITextField! //UpperCamelCase
@IBOutlet var TaskDescription:UITextView! //UpperCamelCase
var taskName:String? //lowerCamelCase
var taskDescription:String? //lowerCamelCase
我像往常一样在ViewDidLoad()上设置Text控件的值:
override func viewDidLoad() {
super.viewDidLoad()
TaskName.text = taskName
TaskDescription.text = taskDescription
}
我像往常一样在prepareForSegue(来自TaskListViewController)中传递数据:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if(segue.identifier == "TaskListSegue"){
let detailViewController = segue.destinationViewController as ToDoTaskViewController
let (task, desc) = m_ToDoListManager.GetTask(TaskListView.indexPathForSelectedRow().row)
println("selected \(task) \(desc)")
detailViewController.taskName = task
detailViewController.taskDescription = desc
}
}
一切实现的方式都是正确的。但是,现在当您运行应用程序时,未设置文本控件的值。实际上,变量的值也未设置。
这里一定发生什么事?
我已经研究了这个问题,并且还提出了解决方案(请参阅下面的答案)。另请参阅下面的Martin R的答案以获取详细说明。我只想与大家分享。我不确定是否有人遇到过此问题。
更新:
这是实际的代码:https : //github.com/Abbyjeet/Swift-ToDoList
这里是一个解释:
NSObject
。setFoo:
因此,对于setter方法既性质TaskName
和taskName
被调用setTaskName:
。
在一个Objective-C文件中,您将得到一个编译器错误
综合属性'taskName'和'TaskName'都声明了setter'setTaskName:'-使用此setter将导致意外行为
但是Swift编译器没有注意到冲突。
问题的小演示:
class MyClass : NSObject {
var prop : String?
var Prop : String?
}
let mc = MyClass()
mc.prop = "foo"
mc.Prop = "bar"
println(mc.prop) // bar
println(mc.Prop) // nil
就你而言
TaskName.text = ...
设置“ taskName”属性,而不是“ TaskName”属性。这些属性具有不同的类型,因此行为是不确定的。
请注意,仅“与Objective-C兼容”属性不会发生此问题。如果您NSObject
在上面的示例中删除了超类,则输出是预期的。
结论:您不能有两个仅在首字母不同的情况下具有两个Objective-C属性。Swift编译器在此应失败并显示错误(就像Objective-C编译器一样)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句