jjzjj

ios - 如何在没有函数的情况下通过引用传递数组? swift

coder 2023-09-08 原文

我有这门课:

class MainView:UIView{

    var categories:[Category]!

}

我想设置类别 arg,但我需要通过引用而不是值来传递它。因为它更高效、更好。

所以如果我这样做:

let mainView  = MainView()
mainView.categories = categoriesData.

然后它按值传递它。

如果我需要通过引用传递它,我可以通过使用 MainView() 中的函数来实现

class MainView:UIView{

    var categories:[Category]!
    fun setCategories(inout categories: Int){
            self.categories = categories;

    }

}

但是如果我不想使用 set 函数,我怎么能通过引用传递它。 例如

mainView.categories = &categoriesData. 但这不起作用?谢谢

最佳答案

Swift 在处理数组时使用 ARC(自动引用计数),它会延迟复制数组,直到其中一个副本被修改:

例如:

var a = [1, 2, 3, 4, 5]
let b = a
let c = a   // 1

a.append(6) // 2

print(a.count)
print(b.count)
print(c.count)

上面第1步,内存中只有一份[1, 2, 3, 4, 5]abc 是对它的引用。

a 在第 2 步被修改时,Swift 给出 a 和数组的新副本以及 bc 继续引用原来的数组。所以现在内存中有 2 个数组副本。


让我们看一个更复杂的例子:

class Person: CustomStringConvertible {
    let name: String
    var friends: [Person] = []

    init(name: String) {
        self.name = name
    }

    var description: String { return name }
}

func createFredsFriends() -> [Person] {
    let barney = Person(name: "Barney")
    let wilma = Person(name: "Wilma")
    let betty = Person(name: "Betty")
    let friends = [barney, wilma, betty]  // 1

    return friends
}

func createFred() -> Person {
    let fred = Person(name: "Fred")

    let friends = createFredsFriends() // 2
    fred.friends = friends             // 3

    return fred
}

let fred = createFred()  // 4

print(fred.friends)  // [Barney, Wilma, Betty]
  • 在第 1 步中,创建了 friend 数组。它由局部变量 friends 引用。

  • createFredsFriends() 返回时,该引用消失,然后在第 2 步中,对数组的唯一引用由局部变量 friends 保存。所有权已经传递了数组。

  • 在第 3 步,对数组的第二个引用已分配给 fredfriends 属性。

  • 在第 4 步,createFred() 已返回,因此局部变量 friends 已消失,不再引用数组。唯一的引用是 fred 对象的属性,该对象由变量 fred 保存。

所以数组只创建了一次,创建了多个对它的引用,最后只有一个对数组的引用,所有这一切都是在没有一个复制操作的情况下完成的。


由于 Swift 数组是值类型并在更改时进行复制,因此您不能传递一个数组,然后期望在复制时更新原始数组。如果您需要该级别的功能,您可以为数组创建一个类包装器,然后始终通过该类的实例访问该数组。

这里我修改了前面的例子来展示它是如何工作的:

// Class to wrap array so that everyone references the same copy
class FriendsWrapper {
    var friends: [Person]

    init(friends: [Person]) {
        self.friends = friends
    }
}

class Person: CustomStringConvertible {
    let name: String
    var friendsWrapper: FriendsWrapper?

    init(name: String) {
        self.name = name
    }

    func addFriend(friend: Person) {
        if let wrapper = friendsWrapper {
            wrapper.friends.append(friend)
        } else {
            friendsWrapper = FriendsWrapper(friends: [friend])
        }
    }

    var description: String { return name }
}

func createFredsFriends() -> [Person] {
    let barney = Person(name: "Barney")
    let wilma = Person(name: "Wilma")
    let betty = Person(name: "Betty")
    let friends = [barney, wilma, betty]

    return friends
}

func createFred() -> Person {
    let fred = Person(name: "Fred")

    let friendsWrapper = FriendsWrapper(friends: createFredsFriends())
    fred.friendsWrapper = friendsWrapper

    // Add friend to Fred object
    fred.addFriend(Person(name: "Bam Bam"))

    // Copy of array in local friendsWrapper is updated
    print(friendsWrapper.friends)  // [Barney, Wilma, Betty, Bam Bam]

    return fred
}

let fred = createFred()

关于ios - 如何在没有函数的情况下通过引用传递数组? swift ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35391394/

有关ios - 如何在没有函数的情况下通过引用传递数组? swift的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  7. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  8. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  9. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  10. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

随机推荐