Динамическое связывание использует vpointer и vtable. Однако динамическое связывание применяется только к указателю на функцию. Механизм динамического связывания отсутствует.
Таким образом, аргумент по умолчанию определяется статически во время компилятора. В этом случае он статически определяется типом bp, который является указателем на базовый класс. Таким образом, data = 10 передается как аргумент функции, а указатель функции указывает на функцию класса Derived: D :: print. По сути, он вызывает D :: print (10).
Следующий фрагмент кода и результирующие выходы четко демонстрируют точку: даже если он вызывает функцию члена Derived call Derived :: resize (int), это передает основной аргумент по умолчанию: size = 0.
virtual void Derived :: resize (int) size 0
#include <iostream>
#include <stdio.h>
using namespace std;
#define pr_dbgc(fmt,args...) \
printf("%d %s " fmt "\n",__LINE__,__PRETTY_FUNCTION__, ##args);
class Base {
public:
virtual void resize(int size=0){
pr_dbgc("size %d",size);
}
};
class Derived : public Base {
public:
void resize(int size=3){
pr_dbgc("size %d",size);
}
};
int main()
{
Base * base_p = new Base;
Derived * derived_p = new Derived;
base_p->resize(); /* calling base member function
resize with default
argument value --- size 0 */
derived_p->resize(); /* calling derived member
function resize with default
argument default --- size 3 */
base_p = derived_p; /* dynamic binding using vpointer
and vtable */
/* however, this dynamic binding only
applied to function pointer.
There is no mechanism to dynamic
binding argument. */
/* So, the default argument is determined
statically by base_p type,
which is pointer to base class. Thus
size = 0 is passed as function
argument */
base_p->resize(); /* polymorphism: calling derived class
member function
however with base member function
default value 0 --- size 0 */
return 0;
}
#if 0
The following shows the outputs:
17 virtual void Base::resize(int) size 0
24 virtual void Derived::resize(int) size 3
24 virtual void Derived::resize(int) size 0
#endif
Просто используйте prepare(for segue: )
, проверьте приведенный ниже код,
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "DropDown"){
let vc = segue.destination as! ViewControllerB
vc.delegate = self
}
}
Проблема, с которой вы столкнулись, заключается в том, что вы создаете экземпляр из ViewControllerB
var instance = ViewControllerB()
и переходите к с другой стороны, он не будет работать, потому что он будет рассматриваться как новый экземпляр, а не как конечный пункт назначения.
Вы можете использовать делегат или экземпляр в приведенном ниже коде. Это будет полезно для всех:
ViewController:
class ViewController: UIViewController {
@IBOutlet weak var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
myTextField.text = "Hello World"
// Do any additional setup after loading the view, typically from a nib.
}
// Without segue
@IBAction func passData(_ sender: Any) {
let sb = storyboard?.instantiateViewController(withIdentifier: "viewcontroller2") as! ViewController2
sb.passText = "Hello World"
//set self to Delegate
sb.delegate = self
//set self to Instance
sb.instance = self
present(sb, animated: true, completion: nil)
}
// With segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let sb = segue.destination as! ViewController2
sb.passTextSegue = "Hello World with segue"
//set self to Delegate
sb.delegate = self
//set self to Instance
sb.instance = self
}
}
extension ViewController : ViewController2Delegate{
func passValue(Str: String) {
print(Str)
}
}
ViewController2:
protocol ViewController2Delegate : class {
func passValue(Str:String)
}
class ViewController2: UIViewController {
//Create instance for Delegate
weak var delegate : ViewController2Delegate?
//Create instance for ViewController
var instance: ViewController?
override func viewDidLoad() {
super.viewDidLoad()
myTextField.text = passText
myTextFieldSegue.text = passTextSegue
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBOutlet weak var myTextField: UITextField!
var passText: String?
@IBOutlet weak var myTextFieldSegue: UITextField!
var passTextSegue: String?
@IBAction func manage(_ sender: UIButton) {
//Pass value using Delegate
delegate?.passValue(Str: "Happy Coding~")
//Pass value using Instance
instance?.myTextField.text = "Happy Coding~ :)"
dismiss(animated: true, completion: nil)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Ваш экземпляр segue отличается от 1 здесь
var instance = ViewControllerB()
Так что вы должны либо представить
self.present(instance,animated:true,completion:nil)
ИЛИ
внутри [ 113]
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DropDown" {
let des = segue.destination as! ViewControllerB
des.delegate = self
}
}