继续这个问题:Is there a reason that Swift array assignment is inconsistent (neither a reference nor a deep copy)? -
我一直在玩Swift中的传递对象并注意到一些奇怪的结果。
为了澄清我使用到(Swift之前)的行为类型,将是Objective C.
的行为。为了举例说明我的一个应用程序(用Obj C编写),我有一个'通知列表'的概念。 - 实际上只是一组自定义对象。
在那个应用程序中,我经常通过我的全球通知'各种viewControllers,提供用于更新列表的UI。
当我将全局数组传递给子viewController时,我将它分配给收件人对象中的本地数组变量。然后,只需更新/更改本地数组这些更改将反映在rootViewController 上的全局数组中。我理解这种行为隐含在Objective C中作为通过引用传递的对象,但这非常方便,我一直试图在Swift中复制这种行为。
然而,当我在Swift中重写我的应用程序时,我已经撞墙了。
我首先尝试将一个 Swift数组字符串 (不是NSMutableArray)从rootViewController传递给子viewController(如上所述)。
传递子视图的数组时,传递子视图:
的行为我传入:
[Bill,Bob,Jack] 然后将此传递的数组分配给本地数组进行本地修改,
然后我将字符串“Frank”附加到本地数组
结果是:
本地数组 = [比尔,鲍勃,杰克,弗兰克]
全局数组 = [比尔,鲍勃,杰克]
对本地数组的任何更改都不会反映回全局数组。 - 对于更改元素会发生相同的结果(不会更改数组的长度)。 )
我还尝试了一个更真实世界的例子 - 通过我的自定义'通知'对象到viewcontroller。 SAME 结果发生时本地分配的自定义对象数组的所有更改都没有反映到传入的原始全局数组中。
这种行为对我来说是不可取的,我假设这里的最佳做法是使用委托协议将修改后的数组(或任何对象)传递回父对象,然后手动更新全局数组? - 如果是这样,这会在Objective C样式行为上产生相当多的工作量。
最后我尝试了 inout 关键字,这有效地让你直接修改传递给目标对象的函数参数var。
更改会反映回全局数组(或对象)然而问题是,如果输入参数已分配给局部变量(要在范围外编辑)对init函数的更改仍然没有反映在全局范围内。
我希望上述内容有道理 - 用Swift真正扼杀了我的工作效率。
我是否遗漏了某些东西,或者预计会出现这种精神分裂症行为?
如果是这样,将修改后的数据传回给代表是什么最佳做法?
答案 0 :(得分:3)
链接的问题提供了答案 - 它是为了表现。
这种行为可能不适合您,但我会说依赖于调用方法来修改参数的副作用是不合乎需要的行为 - 特别是在数据的多线程,多核环境中结构可能会被破坏。
在我看来,依赖副作用的设计存在缺陷。
如果功能需要修改"全球"那么他们应该返回新值,或者如果不可能那么你应该将数组包装在一个对象中并提供适当的函数来操作数据值。
Swift使用数组稍微模糊了内在和对象之间的界限,这使得它有点混乱 - 在Objective-C中,NSMutableArray是一个对象,所以它总是通过引用传递。
为了通知其他对象数据已更改,您可以使用观察者模式。典型的委托模式只有一个注册的委托 - 使用观察者模式,您可以拥有多个注册的观察者。
您可以通过NSNotificationCenter或一组"代表"来完成此操作。前者具有将代码解耦而不是委托
的优点答案 1 :(得分:1)
为什么不创建一个包含数组作为var的Model类。向Model类添加方法以操作数组并将新实例存储在属性中。在启动时创建Model类的单个实例,并将其传递给视图控制器。它们都通过Model或Model类中的方法访问数组。 Swift的行为(在更改大小时复制数组)将从所有视图控制器中隐藏。