问题标签 [swift-structs]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
128 浏览

ios - 将正确的图像传递给 tableviewcell 的问题

这是我的结构...

现在我collectionview在单击按钮时加载了一个图像,我想将此图像传递给tableviewcell. 确实有几个带有名称和 id的collectionview标签已成功传递...但是如何传递图像,我无法弄清楚。以下是到目前为止单击卖出按钮时发生的情况......

这就是我在 tableviewcell 中分配图像和其他数据的方式。这是 cellForRow 的代码 ..(从其中加载单元格的 tableview ..)

这就是数组(传递给 tableview 单元格)获取图像的方式......

0 投票
0 回答
914 浏览

ios - 在 for 循环中快速耗尽内存(4)

我正在循环浏览 PDFDocument 中的所有页面(200 多页),但应用程序崩溃

来自调试器的消息:由于内存问题而终止

pdf 的大小约为 4mb,但循环的每次迭代都会使内存上升约 30mb。这对我来说似乎不正确。我已经设法在我的代码中找到内存被使用的位置,只是不确定如何收回它。尝试将变量设置为零但没有效果。尝试了 for 循环中的代码,autoreleaspool{}但没有效果。

更新:解决了.....有点

玩了一下,我发现不是传递PDFDocument对循环内部的引用,而是为每个循环创建一个新实例,这奇怪地解决了内存问题。我不太明白为什么。PDFDocument是一个类而不是一个结构,所以是通过引用传递的。这意味着它只创建一次,然后在我的循环中引用。那么为什么会导致内存问题呢?

虽然上面的代码清除了内存问题,但它的问题是它太慢了。每个循环需要 0.5 秒,并且有 300 多页我不能接受。有什么加快速度的小窍门吗?PDFDocument或者如果从循环外部引用它为什么不归还内存

进一步更新。似乎它正在调用将内存增加到崩溃点的方法.stringPDFPage

0 投票
2 回答
2134 浏览

swift - 如何在 swift 中轻松复制不可变结构,仅更改某些字段 [如 kotlin 数据类复制方法]?

我有一个有点像这样的快速结构:

以及此状态的可变实例。注意状态中的属性都是 all let,所以结构体本身是不可变的。

我想做的是强制执行允许更新状态的模式,但所有更新都必须是原子的 - 我不想简单地使 a、b 和 c 可变,因为这将允许 a 和 b 独立更改. 我需要控制更新并应用验证(例如,强制执行如果您更改a,您也必须同时更改b

我可以通过简单地覆盖整个结构来做到这一点

但是,如您所见,必须为不变的属性显式引用旧状态 ( _state.c) 是烦人且有问题的,尤其是当您有更多属性时。我的真实示例有 10 个。

在 kotlin 中,它们具有公开“复制”方法的“数据类”,它允许您仅更改所需的参数。如果 swift 支持这样的事情,语法应该是这样的

问题是,= self.aswift 中不存在语法,我不确定我还有哪些其他选项?

任何有关如何解决此问题的解决方案将不胜感激

0 投票
1 回答
161 浏览

swift - swift 实际上对结构做了什么复制省略?

Swift 编程的普遍共识(截至 2018 年 5 月,Swift 4.1,Xcode 9.3)是结构应该是首选,除非您的逻辑明确要求对对象的共享引用。

众所周知,结构的一个问题是它们是按值传递的,因此当您将结构传递给函数或从函数返回时,会产生副本。如果您有一个大型结构(例如其中包含 12 个属性),那么这种复制可能会变得昂贵。

这通常被人们辩护说 swift 编译器和/或 LLVM 可以删除副本(即传递对结构的引用,而不是复制它)并且只需要在您实际改变结构时进行复制。

这一切都很好,但总是用理论术语来谈论——“作为一种优化,LLVM可以省略副本”之类的东西。

我的问题是,谁能告诉我们实际发生了什么?编译器实际上是否删除了副本,或者它只是将来可能存在的理论上的优化?(例如,C# 编译器理论上也可以省略结构副本,但它实际上从未这样做过,Microsoft 建议您不要将结构用于大于 16 字节的内容 [1])

如果 swift 确实省略了 struct 副本,是否有一些解释或启发式来说明它是否以及何时这样做?

注意:我说的是用户定义的结构,而不是像数组和字典这样的 stdlib 内置的东西

[1] https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/choosing-between-class-and-struct

0 投票
1 回答
212 浏览

swift - Swift - 在 Struct 中使用 #available 来初始化变量

我需要根据操作系统版本初始化一个变量。我正在尝试在`struct 中使用#available。我需要在声明时初始化一个变量。

这是我尝试过的代码,

它给了我一个构建错误:

预期声明

代码错误截图

0 投票
1 回答
1130 浏览

swift - 在 Swift 中,如何在对象创建后立即调用函数

我有一些对象,它们是我通过协议扩展提供的函数structs从 JSON 字典 ( [String : Any])初始化的(请参阅使用字典/数组初始化符合 Codable 的对象)。initDecodable

所以基本上,我有看起来像这样的对象:

ObjectModelB包含一个数组ObjectModelA,并且它还有一个属性,我只想在arrayOfObjectModelAVal更改时设置它。

我可以使用didSeton arrayOfObjectModelAVal,但这只会捕获未来对arrayOfObjectModelAVal属性的更改。问题是我正在使用 Web 服务来检索 JSON 数据以创建 ObjectModelB ( ) 数组[[String : Any]],并且我像这样构建它:

我的对象是在compactMap闭包内创建的,并且init不会触发didSet.

我也不能“覆盖”协议提供的 init initDecodable闭包中的那个:),try? ObjectModelB(any: $0)因为我的对象是 astruct并且这不是继承,它只是协议提供的初始化程序。否则,我会“覆盖”init我的对象中的 ,然后只是执行super.init某种变异函数来更新我的复杂属性,然后我会创建我的复杂属性private(set)

我能想到的唯一其他选择是创建我刚刚提到的那个变异函数,并在两个didSetwhenarrayOfObjectModelAVal更改中调用它,然后使用以下内容更新我的对象初始化调用:

但是现在updateProperties任何人都可以随时调用它(这很糟糕,因为它真的很费力),并且不能保证在创建对象数组时它甚至会被调用,因为开发人员可能会忘记做这forEach部分。因此,为什么我想要一种updateProperties在对象初始化后立即自动调用函数的方法。

0 投票
3 回答
1420 浏览

swift - 在结构中快速记忆/缓存惰性变量

我在 Swift 中喝了 struct/value koolaid。现在我有一个有趣的问题,我不知道如何解决。我有一个结构,它是一个容器,例如

当我对此进行编辑时,我会创建副本以便保留撤消堆栈。到目前为止,一切都很好。就像好的教程显示的那样。不过,我对这个人使用了一些派生属性:

在最近的分析中,我注意到 a) 计算 derivedValue 的计算有点昂贵/冗余 b) 在各种用例中并不总是需要计算。

以我经典的 OOP 方式,我会将其设为记忆/惰性变量。基本上,在调用之前让它为零,计算一次并存储它,并在以后的调用中返回所述结果。由于我遵循“制作副本以进行编辑”模式,因此不会破坏不变量。

但是如果它是结构,我不知道如何应用这种模式。我可以做这个:

这有效,直到结构引用该值本身,例如

此时,编译器会抱怨,因为anotherDerivedComputation正在导致接收器发生更改,因此需要标记mutating。将访问器标记为变异是错误的。但是为了咧嘴笑,我尝试了一下,但这会产生一系列新的问题。现在任何地方我都有这样的表达

编译器抱怨是因为参数隐式是非可变的 let 值,而不是 var。

有一个带有延迟/延迟/缓存成员的结构,我是否缺少一种模式?

0 投票
1 回答
476 浏览

swift - Swift Struct 成语替换 OOP 类型继承模式?

假设我有一个适用于 Rectangles 的程序(这是我的实际问题的简化示例),我将其建模为

一个合理化的矩形,基本上是一个具有正宽度和高度的矩形。对于许多操作(例如缩放、平移、联合、相交等),最好保证矩形是合理的。事实上,可以将合理化逻辑实习在一个init(...),这样你就永远无法创建一个不合理的逻辑。但是在某些情况下,您希望支持不合理的结构,至少是暂时的,也许是为了在拖放过程中进行编辑,例如

想要这样做会使将合理化逻辑放在 init() 中会适得其反。

但是另一种方法是在几乎所有地方(除了拖放站点)都在rationalized()调用我的代码。我正在尝试确定是否可以以某种方式使用结构和类型来做到这一点。

如果我使用类,我可以有一个 Rectangle 超类和一个 RationalizedRectangle 子类,其中 RationalizedRectangle 覆盖 init 来完成工作。然后我通常可以使用 RationalizedRectangles(甚至在适当的时候将其指定为类型),但允许通过使用 Rectangle 来编辑它们,并在最后转换为 RationalizedRectangle。

但是 Swift 结构不支持继承。所以我不知道如何惯用地实现这一点。我可以在结构中添加一个 isRationalizing:Boolean,然后在其上进行分支,但这看起来很俗气。

是否有一个基于结构的习语可以在这里工作?

0 投票
2 回答
166 浏览

json - 使用 Swift 解码器从 JSON 数组中提取属性

我有一个使用此调用创建的 JSON 数组:

我正在尝试从数组中的 JSON 对象中获取元素以使用以下代码显示它们:

代码编译但是当我运行它时,我在输出中得到这个错误:

无法将类型“__NSDictionaryM”(0x1063c34f8)的值转换为“NSData”(0x1063c1090)。2018-08-09 09:41:02.666713-0500 TruckMeterLogScanner[14259:1223764] 无法将“__NSDictionaryM”(0x1063c34f8)类型的值转换为“NSData”(0x1063c1090)。

我仍在调查,但任何提示都会有所帮助。

0 投票
4 回答
341 浏览

ios - 如何使用静态方法更改属性值?

在这个简单的游戏中,有一个职业战士,其目的是让两个战士战斗。将生命值降至 0 以下的人将输掉比赛。

为了战斗,有一个静态方法战斗(..),它迭代直到一个战士赢得比赛,由另一个非静态方法攻击(..)支持

object Fighter 的健康应该随着两个对象在游戏中使用 Fight(...) 和 Attack(...) 方法进行战斗而改变。问题是它总是打印相同的战斗机健康状况,并且游戏永远不会结束。我看不出问题出在哪里