微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

swift数组的第一个或过滤器函数未提供正确的参考对象

如何解决swift数组的第一个或过滤器函数未提供正确的参考对象

在加载viewdidload之前,我已经在viewcontroller中定义了一个结构

struct CustomFilterButton {
var Id : Int = 0;
var Name : String = "";
var selected : Bool = false;
}

然后我在全局中为其创建引用

var customButtons = [CustomFilterButton]();

然后在我的viewdidload中,我在customButtons数组中附加了一些customFilterButton对象

customButtons.append(CustomFilterButton.init(Id: 1,Name: "A",selected: false))
customButtons.append(CustomFilterButton.init(Id: 2,Name: "B",selected: false))
customButtons.append(CustomFilterButton.init(Id: 3,Name: "C",selected: true))
customButtons.append(CustomFilterButton.init(Id: 4,Name: "D",selected: false))

在viewdidload或任何其他函数中,当我尝试使用first或filter来获取数组中的对象并对其进行更改时,但这不起作用。

    print(customButtons[0].selected);
    print("--")
    var bt = customButtons.first{
        $0.Id == 1
    }
    bt?.selected = true;
    print(bt?.selected);
    print(customButtons[0].selected);

这是结果

false
--
Optional(true)
false

过滤器也一样! 我错过了什么还是做错了什么?

注意:我需要获取首先找到的对象或过滤器并进行更改,而不是对其进行硬拷贝

解决方法

处理Struct时,必须了解它是一种值类型。

因此,这意味着每次传递值时,它都是该值的COPY,而不是引用

当您这样做时:

var bt = customButtons.first{
    $0.Id == 1
}

您要让编译器检索CustomFilterButton为1的Id的副本,并将该副本分配给您的bt变量。

要解决此问题,您可以通过元素的索引访问元素并直接修改其值而无需传递它(分配给新变量)

// Get the index of the element you're trying to modify
if let indexYouWantToModify = customButtons.firstIndex(where: {$0.Id == 1}){
    // Modify it directly through its index 
    customButtons[indexYouWantToModify].selected = true
}

哦,尽管将Struct更改为Class很适合您,但我认为对于这个小用例来说是不必要的。结构和类具有自己的利益和取舍。我不确定从长远来看您打算在此CustomFilterButton上做什么,所以我建议您阅读this文章并自己决定!

,
var bt = customButtons.first{
   $0.Id == 1
}

此刻bt与您的customButtons[0]没有任何关系,其值已被复制。

,

按索引访问项目

    print(customButtons[0].selected);
    print("--")
    var offset = 0
    var bt = customButtons.enumerated().first{
        if $0.element.Id == 1 {
            offset = $0.offset
            return true
        }
        return false
    }
    customButtons[offset].selected = true;
    print(customButtons[0].selected);
,

下面的代码获得customButtons第一个元素,但没有复制相同的地址,而是创建了new。因此,btcustomButtons[0]的地址不同。

var bt = customButtons.first{
    $0.Id == 1
}

因此,当您运行print(customButtons[0].selected)时,您仍在调用旧地址值为:

CustomFilterButton.init(Id: 1,Name: "A",selected: false)

您只需将此行添加到代码中

  customButtons[0] = bt!

所有代码:

    print(customButtons[0].selected);
    print("--")
    var bt = customButtons.first{
        $0.Id == 1
    }
    bt?.selected = true;
    print(bt?.selected);
    customButtons[0] = bt!
    print(customButtons[0].selected);

输出:

false
--
Optional(true)
true
,

您应该使用class而不是struct

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。