加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – __weak NSString * text = self.textField.text

发布时间:2020-12-16 06:50:29 所属栏目:百科 来源:网络整理
导读:我想我可能犯了一个愚蠢的错误,但我无法弄清楚原因: 我有一个方法和块来处理一些网络API,如: -(IBAction)confirm:(id)sender { __weak typeof(self) weakSelf = self; __weak NSString *anotherNumber = self.nextPhoneTextField.text; [SharedInstance bi
我想我可能犯了一个愚蠢的错误,但我无法弄清楚原因:

我有一个方法和块来处理一些网络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
>将新的复制NSString转换为anotherNumber
>由于anotherNumber是__weak,它不会保留对象(NSString),它将保持对该对象的__weak引用,并且在此函数脱离上下文后它变为零.

要确认此行为,您可以在设置其值并在不同的上下文中直接记录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?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读