objective-c – __weak NSString * text = self.textField.text
我想我可能犯了一个愚蠢的错误,但我无法弄清楚原因:
我有一个方法和块来处理一些网络API,如: -(IBAction)confirm:(id)sender { __weak typeof(self) weakSelf = self; __weak NSString *anotherNumber = self.nextPhoneTextField.text; [SharedInstance bindNewPhoneNumber:self.nextPhoneTextField.text pinCode:self.verifyCodeTextField.text sucess:^(id result) { // update phone number SharedInstance.phoneNumber = anotherNumber; }]; } 在块之前,我可以看到newNumber有正确的值, 但是,当调用块时,newNumber为nil,而不是文本.但我能够打印weakSelf.nextPhoneTextField.text,它没有被更改. 任何解释都表示赞赏! 更新: 创建示例项目后,我发现它不可重现.弱字符串指针具有有效文本.然后我开始调试它,我发现, 为了避免使用new关键字,我将指针名称更改为anotherNumber 在我的真实项目中,当调用__weak NSString * anotherNumber = self.nextPhoneTextField.text; anotherNumber有一个新地址,而不是self.nextPhoneTextField.text;地址: (lldb) p anotherNumber (__NSCFString *) $2 = 0x00007f88b3ff2960 @"12345678901" (lldb) p self.nextPhoneTextField.text (__NSCFString *) $3 = 0x00007f88b15f8690 @"12345678901" 但是在示例项目中,我有类似的功能, - (void)clickBlock:(void (^)(NSString * string))block { if (block) { block(@"haha"); } } - (IBAction)clicked:(id)sender { __weak typeof(self) weakSelf = self; __weak NSString *text = self.textField.text; [self clickBlock:^(NSString *string) { NSLog(text); NSLog(string); }]; } 它是相同的地址: (lldb) p text (NSTaggedPointerString *) $2 = 0xa000000747365744 @"test" (lldb) p self.textField.text (NSTaggedPointerString *) $3 = 0xa000000747365744 @"test" 并且班级类型也改变了…寻找答案!!! 另一个更新: 我删除了块,只需创建两个弱指针,其中包含一些字符串,如“hello”和“12345678901”,formmer有一个相同的地址并标记为NSTaggedPointerString,但后者有不同的地址并标记为NSCFString 在我看来,一旦文本达到特定长度,它将具有NSCFString和不同的地址,并且经过一些测试,赏金是9.一次超过9个字,它将是NSCFString,在iOS 9.1 iPhone 6S模拟器上测试. 在iOS 8.4模拟器上,所有不同长度的字符串都会产生不同的mem地址和NSCFString 示例项目:https://github.com/liuxuan30/WeakStringPointer 解决方法
__weak NSString * anotherNumber = self.nextPhoneTextField.text;
使用此行,NSString按值复制而不是通过引用复制,因此在将NSString分配给另一个NSString后,它会创建它的新副本并创建对新创建的副本的引用而不是原始副本,并且因为引用较弱,当前函数脱离上下文后,对象将为nil, 如果您尝试更改文本字段的文本,它将只更改textFields文本而不更改anotherNumber对象. NSString *test = self.nextPhoneTextField.text; self.nextPhoneTextField.text = @"Something else"; NSSLog(@"Test object contains %@,the textField contains %@ ",test,self.nextPhoneTextField.text); 您的代码如下: >从self.nextPhoneTextField.text创建一个新的Copy NSString 要确认此行为,您可以在设置其值并在不同的上下文中直接记录anotherNumber __weak NSString *anotherNumber = self.nextPhoneTextField.text; NSString *strongAnotherNumber = self.nextPhoneTextField.text; NSLog(@"Weak number - %@,strong - %@",anotherNumber,strongAnotherNumber); dispatch_async(dispatch_get_main_queue(),^{ NSLog(@"Block Weak number - %@,strongAnotherNumber); }); 请看看Why do weak NSString properties not get released in iOS? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |