Ios 如何循环遍历动态大小的数组,并将属性作为变量传递给变量函数?

Ios 如何循环遍历动态大小的数组,并将属性作为变量传递给变量函数?,ios,swift,variadic-functions,nsexpression,Ios,Swift,Variadic Functions,Nsexpression,我有一个有趣的问题,不确定我想做的事情是否可行。如果不是,我想我的问题还有其他解决办法 我正在为iOS使用Mapbox(MapKit备选方案)。Mapbox具有样式层,可用于为地图上的不同管脚设置不同的图像。这是通过将层的iconImageName设置为不同的值来完成的,具体取决于它所处理的贴图管脚。作为样式层的iconImageName给定的值是一个NSExpression,在这个值中,我们将一个格式作为字符串和任何其他数量的NSExpression传递,以使它们适合该格式。下面是一个从不是动

我有一个有趣的问题,不确定我想做的事情是否可行。如果不是,我想我的问题还有其他解决办法

我正在为iOS使用Mapbox(MapKit备选方案)。Mapbox具有样式层,可用于为地图上的不同管脚设置不同的图像。这是通过将层的
iconImageName
设置为不同的值来完成的,具体取决于它所处理的贴图管脚。作为样式层的
iconImageName
给定的值是一个
NSExpression
,在这个值中,我们将一个格式作为字符串和任何其他数量的
NSExpression
传递,以使它们适合该格式。下面是一个从不是动态的图像创建样式层的示例,即这些图像被硬编码到应用程序中

//Create the layer
let ports = MGLSymbolStyleLayer(identifier: "ports", source: source)
//Create a default shape
let defaultShape = NSExpression(forConstantValue: "grayMarker")

//For every pin in the 'ports' layer, we are going to look at its 
//'type' property. If 'type' is equal to the string 'redPin', its image 
//should be the one registered with the name 'redMarker'. If 'type' is 
//equal to the string 'bluePin', its image should be the one registered 
//with the name 'blueMarker'...and so on. If 'type' doesn't match 
//anything outlined here, then set the pin's image to the default 
//shape.
ports.iconImageName = NSExpression(format: "MGL_MATCH(type, 'redPin', %@, 'bluePin', %@, 'greenPin', %@, 'grayPin', %@, %@)", NSExpression(forConstantValue: "redMarker"), NSExpression(forConstantValue: "blueMarker"), NSExpression(forConstantValue: "greenMarker"), NSExpression(forConstantValue: "grayMarker"), defaultShape)

//Add the layer to the map's style
self.mapStyle!.addLayer(ports)
因此,当信息硬编码到应用程序中时,这是非常容易做到的。问题是,我有一系列从API请求返回的“pin类型”,我可能需要在将来进行更改。这些pin类型有一个与之关联的photoUrl

由于pin类型的数量将来可能会发生变化,我必须在我的应用程序中提取类型,将它们解析为一个自定义对象数组,循环遍历每个类型,并将它们的信息添加到NSExpression的格式中。下面是我如何做到这一点的示例:

//Create a new style layer, like in the previous example
let icons = MGLSymbolStyleLayer(identifier: "icons", source: source)

//Create a prefix type string for our format string. We will modify 
//this based on the data in our categories 
var format = "MGL_MATCH(type, "

//Loop through the array and modify our format string to include our 
//pin type
for pinType in self.pinTypes {
    format += "'\(pinType.id ?? "")', %@, "
}

//Add the suffix to the format string
format += "%@)"
我们的“格式”字符串的最终结果将始终是这样的(尽管有不同数量的pinTypes):

因此,我能够从API请求中提取动态数据来创建格式字符串,但现在是最困难的部分。如何将动态数量的参数传递到函数中

请注意,下一步是将
iconImageName
属性设置为可以接受任意数量参数的NSExpression。回想一下我们的第一个硬编码数据示例:

ports.iconImageName = NSExpression(format: "MGL_MATCH(type, 'redPin', %@, 'bluePin', %@, 'greenPin', %@, 'grayPin', %@, %@)", NSExpression(forConstantValue: "redMarker"), NSExpression(forConstantValue: "blueMarker"), NSExpression(forConstantValue: "greenMarker"), NSExpression(forConstantValue: "grayMarker"), defaultShape)
第一个参数是格式字符串,所有其他参数都是“填充”该格式字符串的
NSExpression
s。设置样式层的iconImageProperty时,如何“循环”pinTypes数组,为每个pinTypes数组创建一个单独的
NSExpression
,并将每个
NSExpression
作为参数传递

TLDR
在将参数传递到一个可以接受任意数量参数的函数中时,是否有一种方法可以循环通过一个大小可能不同的数组,从该数组中的每个元素创建一个对象,然后将其作为参数传递到可以接受任意数量参数的函数中?

我可能误解了这个问题。我不知道您是否需要一种通用的方法来执行此操作,但是
NSExpression
有一个接受数组的init:

所以你可以这样做:

let defaultShapeExpression = NSExpression(forConstantValue: "grayMarker")
// Either do clean array or add your initial arguments
var expressionArguments = [Any]()
var format = "MGL_MATCH(type, "

for pinType in self.pinTypes {
    format += "'\(pinType.id ?? "")', %@, "
    expressionArguments.append(NSExpression(pinType.iconImageProperty))
}

format += "%@)"
expressionArguments.append(defaultShapeExpression)

let expression = NSExpression(format: format, argumentArray: expressionArguments)

希望这能有所帮助。我坐在我的桌面上,所以我自己无法真正测试任何东西。

非常感谢,我以前从未使用过N表达式,但我知道它们是Npredicate的对应项。我想我可以将数组作为参数传递,但还没有研究NSExpression是否有用于获取数组的init。Mapbox示例的init采用格式字符串,然后采用可变参数。让我试试看,然后再打给你!这实际上非常有效。我不得不稍微编辑一下Nexpression,因为我对它们的工作原理的理解有点偏差,但只要Nexpression数组是正确的,就可以将数组作为参数传递。
let defaultShapeExpression = NSExpression(forConstantValue: "grayMarker")
// Either do clean array or add your initial arguments
var expressionArguments = [Any]()
var format = "MGL_MATCH(type, "

for pinType in self.pinTypes {
    format += "'\(pinType.id ?? "")', %@, "
    expressionArguments.append(NSExpression(pinType.iconImageProperty))
}

format += "%@)"
expressionArguments.append(defaultShapeExpression)

let expression = NSExpression(format: format, argumentArray: expressionArguments)