0

我想传递一些额外的信息,CLBeacon所以我创建了一个名为CLBeaconExtender. 问题是在执行代码时,它给了我这个错误

NSArray 元素无法匹配 Swift Array 元素类型

这是代码:


CLBeacon 的子类

class CLBeaconExtender: CLBeacon{
    var id: String!
}

主类

class beaconController_1: UIViewController, CLLocationManagerDelegate {

    var beacon_collection: UICollectionView!
    var location_manager = CLLocationManager()
    var beacon_manager = [CLBeaconExtender]()
    var beacon_region = [CLBeaconRegion]()

  // Other code that i don't paste

  func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        if !beacons.isEmpty {
            beacon_manager = beacons as! [CLBeaconExtender]
            beacon_manager[0].id = "hello world"  // here appear the error
            beacon_collection.reloadData()
        }
        else{
            if beacon_manager.count != 0 {
                beacon_manager = beacons as! [CLBeaconExtender]
                beacon_collection.reloadData()
            }
        }
    }

谁能解决我这个问题或给我一个例子?

编辑

我认为错误是由这一行引起的:

beacon_manager = beacons as! [CLBeaconExtender]

编辑 2

对不起我的英语,我的目标是创建一个collectionview显示我周围的所有信标,并在每次didRangBeacons调用时更新列表,此外每个collectionviewcell都应包含引用相应信标的特定文件音频。因此,当我点击特定信标的特定单元格时,它开始播放特定声音。我的问题是处理beacon_manager数组。在第一个循环中didRangeBeacons一切都很好,因为!beacon_manager.indices.contains(i)return!false所以它将执行if条件,并将填充所有beacon_manager. 比在didRangeBeaconsif 条件的第二个循环中将返回!true,因此执行的代码将是else条件。这里系统将在执行 beacon_manager.remove(at: i)where iis 0 和 beacon_manager[0] 存在时崩溃。

崩溃向我展示了带有错误的 AppDelegate 类:

EXEC_BAD_ACCESS 代码=1 地址= 0x8

希望你现在明白了。

   func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
    if !beacons.isEmpty {
        var i = 0
        for beacon in beacons {
            let bx = CLBeaconExtender(b: beacon, sID: "hello world")
            if(!beacon_manager.indices.contains(i)){  //check if beacon_manager array exist at i if no create it, if yes update it
                beacon_manager.insert(bx, at: i)
            }
            else{
                beacon_manager.remove(at: i)
                beacon_manager.insert(bx, at: i)

            }
            print(beacon_manager[i].id)
            i+=1
        }

        print(beacon_manager.count,beacons.count)
        beacon_collection.reloadData()
    }
    else{
        if beacon_manager.count != 0 {
            //do other things
        }
    }
}
4

2 回答 2

0

类型的问题:-

1)Array 是一个 struct,因此,它是 Swift 中的一个值类型。

2)NSArray是一个不可变的Objective-C 类,因此它是一个引用类型。

于 2017-05-16T13:54:18.210 回答
0

你不能简单地说“这个对象现在是另一种类型”并神奇地改变了这个对象。例如:

    let x = UIView()
    let y = x as! UIImageView

如果您尝试运行这两行,则会收到如下错误:

无法将“UIView”(0x107fa44c0)类型的值转换为“UIImageView”(0x107fa5c08)。

所以,这就是你在这里尝试做的事情:

beacon_manager = beacons as! [CLBeaconExtender]

您是在说“我声明这个 CLBeacon 对象的 NSArray 现在是 CLBeaconExtender 对象的数组!” 事情就不是那样的。

您尝试做的一种方法是将您的 CLBeaconExtender 类定义为:

class CLBeaconExtender: CLBeacon {
    var id: String!
    var bcn: CLBeacon!

    convenience init(b: CLBeacon, sID: String) {
        self.init()
        bcn = b
        id = sID
    }
}

然后,在您的didRangeBeacons函数中:

func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {

    for beacon in beacons {
        let bx = CLBeaconExtender(b: beacon, sID: "hello world")
        beacon_manager.append(bx)
    }

    // other code...
}

当然,您不会想要这样做,因为您最终会附加许多相同的信标对象,所有这些对象的 id 都是“hello world”。但是,希望这可以帮助您了解您遇到的错误,并帮助您解决问题。

于 2017-05-16T15:03:59.900 回答