将数据传回以前的视图控制器(实例成员不能用于类型错误)
Passing data back to previous view controller (Instance member cannot be used on type error)
我有 2 个值来跟踪我的用户可以在应用程序中购买的各种福利的当前值。我想在 purchaseViewController 中更新它们,并在 purchaseViewController 被关闭后在以前的视图控制器中使用它们。我尝试用 protocol/delegate 和回调来做到这一点。但是,我得到的错误基本相同,都说 "Instance member 'delegate/callback' cannot be used on type 'purchasesViewController'"。这是我第一次尝试传回数据,我主要只是按照教程进行操作,可能错过了其中的一步,但我认为这两种方法都会出现相同类型的错误,这很奇怪。
父视图控制器上的代码:
func sendBack(staticIncreases: Int, percentIncreases: Int) { //Protocol function
self.avalibleIncreases = staticIncreases
self.currentPercentIncreases = percentIncreases
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "improveFromOpen"{
let next = segue.destination as! purchasesViewController
next.currentPercentIncreases = currentPercentIncreases
next.username = username
next.avalibleIncreases = avalibleIncreases
purchasesViewController.delegate = self //Error "Instance member 'delegate' cannot be used on type 'purchasesViewController'"
purchasesViewController.callback = { result in //Error "Instance member 'delegate' cannot be used on type 'purchasesViewController'"
self.avalibleIncreases = result[0]
self.currentPercentIncreases = result[1]
}
}
purchaseViewController 上的代码:
protocol updateBoosts {
func sendBack(staticIncreases: Int, percentIncreases: Int)
}
class purchasesViewController: UIViewController {
var delegate: updateBoosts? = nil
var callback : (([Int])->())?
var username: String!
var currentPercentIncreases: Int!
var avalibleIncreases: Int!
func sendBackVals(){
if self.delegate != nil {
self.delegate?.sendBack(staticIncreases: avalibleIncreases, percentIncreases: currentPercentIncreases)
}
let out = [avalibleIncreases!, currentPercentIncreases] as [Int]
callback?(out)
}
override func viewWillDisappear(_ animated: Bool) {
sendBackVals()
}
知道我的错误在哪里吗?
您的代码存在一些设计问题。
您应该同时使用 delegate
或 closure
,因为两者的用途相同。否则,同样的事情会被执行两次。
如果您使用委托,则必须按如下所述对您的协议进行更改。此外,您还必须确认协议。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "improveFromOpen"{
let next = segue.destination as! purchasesViewController
next.currentPercentIncreases = currentPercentIncreases
next.username = username
next.avalibleIncreases = avalibleIncreases
next.delegate = self
}
}
确认协议
假设您要获取回调的当前视图控制器是 HomeViewController
// Confirming the protocol
extension HomeViewController: UpdateBoostsDelegate {
func sendBack(staticIncreases: Int, percentIncreases: Int) {
// write code here for handling the callback
}
}
如果您想使用闭包,请移除委托。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "improveFromOpen"{
let next = segue.destination as! purchasesViewController
next.currentPercentIncreases = currentPercentIncreases
next.username = username
next.avalibleIncreases = avalibleIncreases
next.callback = { result in
self.avalibleIncreases = result[0]
self.currentPercentIncreases = result[1]
}
}
// Would be good if you add the semantic to protocol name
protocol UpdateBoostsDelegate: class {
func sendBack(staticIncreases: Int, percentIncreases: Int)
}
PurchaseViewController
中的一些更正
class purchasesViewController: UIViewController {
// Make it weak so that no retain cycle is formed
weak var delegate: UpdateBoostsDelegate?
// rest code will follow ....
建议
- 对于类、struct、enum、protocol,每个单词的第一个字符应该总是大写。
- 协议应该有语义,即如果创建它是为了通知事件,则添加 Delegate 后缀,或者如果创建它是为了满足数据需求,则添加 数据源协议名称中的后缀。
我有 2 个值来跟踪我的用户可以在应用程序中购买的各种福利的当前值。我想在 purchaseViewController 中更新它们,并在 purchaseViewController 被关闭后在以前的视图控制器中使用它们。我尝试用 protocol/delegate 和回调来做到这一点。但是,我得到的错误基本相同,都说 "Instance member 'delegate/callback' cannot be used on type 'purchasesViewController'"。这是我第一次尝试传回数据,我主要只是按照教程进行操作,可能错过了其中的一步,但我认为这两种方法都会出现相同类型的错误,这很奇怪。
父视图控制器上的代码:
func sendBack(staticIncreases: Int, percentIncreases: Int) { //Protocol function
self.avalibleIncreases = staticIncreases
self.currentPercentIncreases = percentIncreases
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "improveFromOpen"{
let next = segue.destination as! purchasesViewController
next.currentPercentIncreases = currentPercentIncreases
next.username = username
next.avalibleIncreases = avalibleIncreases
purchasesViewController.delegate = self //Error "Instance member 'delegate' cannot be used on type 'purchasesViewController'"
purchasesViewController.callback = { result in //Error "Instance member 'delegate' cannot be used on type 'purchasesViewController'"
self.avalibleIncreases = result[0]
self.currentPercentIncreases = result[1]
}
}
purchaseViewController 上的代码:
protocol updateBoosts {
func sendBack(staticIncreases: Int, percentIncreases: Int)
}
class purchasesViewController: UIViewController {
var delegate: updateBoosts? = nil
var callback : (([Int])->())?
var username: String!
var currentPercentIncreases: Int!
var avalibleIncreases: Int!
func sendBackVals(){
if self.delegate != nil {
self.delegate?.sendBack(staticIncreases: avalibleIncreases, percentIncreases: currentPercentIncreases)
}
let out = [avalibleIncreases!, currentPercentIncreases] as [Int]
callback?(out)
}
override func viewWillDisappear(_ animated: Bool) {
sendBackVals()
}
知道我的错误在哪里吗?
您的代码存在一些设计问题。
您应该同时使用 delegate
或 closure
,因为两者的用途相同。否则,同样的事情会被执行两次。
如果您使用委托,则必须按如下所述对您的协议进行更改。此外,您还必须确认协议。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "improveFromOpen"{
let next = segue.destination as! purchasesViewController
next.currentPercentIncreases = currentPercentIncreases
next.username = username
next.avalibleIncreases = avalibleIncreases
next.delegate = self
}
}
确认协议
假设您要获取回调的当前视图控制器是 HomeViewController
// Confirming the protocol
extension HomeViewController: UpdateBoostsDelegate {
func sendBack(staticIncreases: Int, percentIncreases: Int) {
// write code here for handling the callback
}
}
如果您想使用闭包,请移除委托。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "improveFromOpen"{
let next = segue.destination as! purchasesViewController
next.currentPercentIncreases = currentPercentIncreases
next.username = username
next.avalibleIncreases = avalibleIncreases
next.callback = { result in
self.avalibleIncreases = result[0]
self.currentPercentIncreases = result[1]
}
}
// Would be good if you add the semantic to protocol name
protocol UpdateBoostsDelegate: class {
func sendBack(staticIncreases: Int, percentIncreases: Int)
}
PurchaseViewController
class purchasesViewController: UIViewController {
// Make it weak so that no retain cycle is formed
weak var delegate: UpdateBoostsDelegate?
// rest code will follow ....
建议
- 对于类、struct、enum、protocol,每个单词的第一个字符应该总是大写。
- 协议应该有语义,即如果创建它是为了通知事件,则添加 Delegate 后缀,或者如果创建它是为了满足数据需求,则添加 数据源协议名称中的后缀。