我有两个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
很好
答案 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时它指向的对象被解除分配。)因此需要strong
或copy
。
答案 1 :(得分:1)
添加到@sergio回复,我想解释为什么第一个_TF_phoneOrEmail
不起作用,但第二个做了。您只能在String
和NSString
的情况下找到此信息。
您的_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