为什么我不能使用prepareForSegue传递值?

时间:2014-07-12 07:25:22

标签: ios objective-c segue

我有两个UIViewControllers。在ViewController我有代码:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"ToResetPwd_NumberSegue"])
{
    ResetPwdBySmsCodeViewController* vc = (ResetPwdBySmsCodeViewController*)[segue destinationViewController];
    vc.phone_no = _TF_phoneOrEmail.text;//TF_phoneOrEmail is a UITextField
    vc.test = @"dagaga";
}

}

在B .h 我有代码

@interface ResetPwdBySmsCodeViewController : UIViewController<UITextFieldDelegate>
@property (weak, nonatomic) NSString *phone_no;
@property (weak, nonatomic) NSString *test;
@end

在B .m

我可以获得_test的值,但不能获得_phone_no

的值

我确信vc.phone

中的prepareForSegue很好

3 个答案:

答案 0 :(得分:6)

您应该将B ViewController中的2个属性声明为strong,或者更好地声明为copy

@interface ResetPwdBySmsCodeViewController : UIViewController<UITextFieldDelegate>
@property (strong, nonatomic) NSString *phone_no;
@property (strong, nonatomic) NSString *test;
@end

您可以获得_test的原因是您要为其分配一个文字字符串值,该值由编译器在特定内存区域中分配。因此,它永远不会被释放,weak变量将无限期地指向它(直到您明确地为_test分配新值,即。)

另一方面,当您访问vc.phone_no属性时,您可以从另一个可能不存在的对象中分配weak属性(因为当weak属性为nil-ed时它指向的对象被解除分配。)因此需要strongcopy

答案 1 :(得分:1)

添加到@sergio回复,我想解释为什么第一个_TF_phoneOrEmail不起作用,但第二个做了。您只能在StringNSString的情况下找到此信息。

您的_TF_phoneOrEmail是在运行时创建的对象。编译器在分配,启动和递增引用计数时生成代码(指令)。因此,当您分配weak引用时,从一个控制器导航到另一个控制器时,引用计数不会递增。 (您应该尝试{@ 1}}或assign,就像@sergio所提到的那样)。

另一方面,当您声明copy时,指针由编译器生成,但是使用test对象。这是有趣的。这是C中的内置优化,当您声明一个字符串(注意:不是@"dagga"实例)时,创建保持值(String)的String的新对象实例的指令没有生成。如果遇到进程和线程内部,您将意识到进程内存中有一个名为@"dagga"的内存段。该过程(基本上执行编译器生成的指令)本身没有足够的权限写入此内存:它只能从中读取。在此内存中创建Code对象(其指令不是由编译器生成的)。它不完全是一个对象,它只是一个保存值(String)的直接内存。

所以,甚至,当他提到“直到你明确地改变它的价值,那就是”时,@ sergio是错误的。你不能。尝试操纵字符串(_test),您的应用程序将崩溃。

如果您已将其声明为@"dagga",则编译器将生成在堆/堆栈内存中创建对象实例的指令,但您声明为文字,在任何执行时都无法释放。过程

希望我很清楚。

答案 2 :(得分:1)

您需要使您的属性强大或复制以声明内存的所有权。您将它们设置为弱,这意味着您不会声明所有权,如果没有其他变量具有对数据的强引用,则数据将消失。

您总是希望使用NSString对象的副本,因为NSString有一个可变版本,这意味着您的数据可以在您没有意识到的情况下进行更改。

@interface ResetPwdBySmsCodeViewController : UIViewController<UITextFieldDelegate>
@property (copy, nonatomic) NSString *phone_no;
@property (copy, nonatomic) NSString *test;
@end