Why can't I pass value using prepareForSegue?

泄露秘密 提交于 2019-12-22 09:39:10

问题


I have two UIViewControllers .In A ViewController I have code:

- (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";
}

}

In B .h I have code

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

In B .m

I can get the value of _test,but not _phone_no

I am sure that vc.phone is well in the prepareForSegue


回答1:


You should declare the 2 properties in B ViewController as strong or even better as copy:

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

The reason why you can get _test is that you are assigning it a literal string value, which is allocated by the compiler in a specific memory area. It is thus never deallocated and the weak variable will indefinitely point at it (until you explicitly assign a new value to _test, that is.)

On the other hand, you assign vc.phone_no a property from another object that might not exist anymore when you access the weak property (since a weak property is nil-ed when the object it points to is deallocated.) Hence the need for strong or copy.




回答2:


Adding to @sergio response, I want to explain why the first one _TF_phoneOrEmail did not work, but the second one did. This you will find only in case of String and NSString's.

Your _TF_phoneOrEmail is an object created on runtime. The compiler generates code (instructions) in allocing, initing and incrementing reference count. Hence while you navigate from one controller to another since you are assigning a weak reference, the reference count is not incremented. (You should rather try with assign or copy like @sergio has mentioned).

On the other hand, when you declare test, the pointers are generated by compilers, but take the @"dagga" object. This is interesting. This is a inbuilt optimisation in C, that when you declare a string (Note: not a String instance) the instructions to create the new object instance of String holding the value (@"dagga") are not generated. If you have come across process and threads internals, you will realise there is a memory segment called Code in the process memory. The process (which basically executes the instructions generated by compiler) itself, doesn't have enough permissions to write to this memory: it can only read from it. The String object (whose instructions are not generated by the compiler) is created in this memory. It's not exactly a object, its just a direct memory holding the value(@"dagga").

So even, @sergio was wrong when he mentioned "until you explicitly change its value, that is". You cannot. Try manipulating the string (_test) and your app will crash.

If you had declared it as [NSString stringWithString:@"dagga"], the compiler would have generated the instructions to create an object instance in heap/stack memory, but you declared as a literal, which cannot be deallocated at any executing time of the process.

Hope I'm clear.




回答3:


You need to make your properties either strong or copy to claim ownership for the memory. You have them set to weak, which means you don't claim ownership and the data will disappear if no other variable has a strong reference to the data.

You always want to use copy for NSString objects because there is a mutable version of NSString, which means that your data could be changed without you realizing it.

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


来源:https://stackoverflow.com/questions/24710692/why-cant-i-pass-value-using-prepareforsegue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!