2015-10-08 3 views
0

Точкой этой функции является определение ближайшего маяка. Если вы запустите этот код, печать печати "THING WAS SET TO 0 THIS SHOULD ONLY HAPPEN AT FIRST" печатает снова и снова.Словарь в Swift не работает?

Я не понимаю, почему это происходит. Что-то в словарях здесь, что я не понимаю? Не следует устанавливать значение словаря на каждом маяке равным 0 изначально, сделать так, чтобы в любое будущее значение словаря, оцененного на этом маяке, должно быть ZERO и NOT NIL ??

У меня есть три маяка, сидящие на столе впереди меня, когда я запускаю код на своем iPhone 6S. Я сидел здесь, пытаясь решить это почти весь день.

Кроме того, словарь первоначально пуст и игнорирует код таймера.

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) { 
    if beaconsHaveBeenFound == false { 
     self.timeOutTimer = NSTimer.scheduledTimerWithTimeInterval(30, target: self, selector: "locationDeterminationHasTimedOut:", userInfo: nil, repeats: false) 
    } 

    print("beacons were found") 
    for beacon in beacons { 
     if nearestBeaconsDictionary.indexForKey(beacon) == nil { 
      print("THING WAS SET TO 0 THIS SHOULD ONLY HAPPEN AT FIRST") 
      nearestBeaconsDictionary[beacon] = 0 
     } 
    } 

    nearestBeaconsDictionary[beacons.first!] = nearestBeaconsDictionary[beacons.first!]! + 1 
    self.beaconsHaveBeenFound = true 

    for beaconIntPair in nearestBeaconsDictionary { 
     if beaconIntPair.1 == 60 { 
      self.timeOutTimer.invalidate() 
      self.beaconsHaveBeenFound = false 
      print("a beacon has been verified 60 times") 
      self.nearestBeacon = beaconIntPair.0 
      let myUUID = NSUUID(UUIDString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D") 
      let myRegion = CLBeaconRegion(proximityUUID: myUUID!, identifier: "CompanyBeacons") 
      manager.stopRangingBeaconsInRegion(myRegion) 
      NSNotificationCenter.defaultCenter().postNotificationName("foundNearestBeacon", object: nil) 
      NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshRequested:", name: "refreshRequested", object: nil) 
     } 
    } 
} 
+0

Где 'nearestBeaconsDictionary' объявлен? – Lance

+0

В собственность делегата. Весь этот код находится в делегате. – jonathanlv7

+0

Можете ли вы объяснить, почему вы вызываете 'indexForKey'? Это необычная вещь! – matt

ответ

1

Проблема заключается в том, что код использует CLBeacon объект в качестве ключа к Swift Dictionary, и ожидая, что она соответствует другой CLBeacon объект от предыдущего в пределах обратного вызова. Это не сработает.

Почему? Поскольку два объекта CLBeacon не обязательно равны (как определено протоколом Hashable, который Swift использует для ключей Dictionary), даже если они имеют одинаковые идентификаторы. Объекты имеют другие поля, такие как accuracy и rssi, которые меняются. В результате nearestBeaconsDictionary.indexForKey(beacon) всегда будет возвращать false, потому что с точки зрения Hashable каждый маяк, с которым он сталкивается, всегда отличается.

Решение состоит в использовании другого ключа для Dictionary. Я часто определяют метод, как это:

func keyForBeacon(beacon: CLBeacon) -> String { 
    return "\(beacon.proximityUUID) \(beacon.major) \(beacon.minor)" 
} 

Тогда код может быть изменен на:

if nearestBeaconsDictionary.indexForKey(keyForBeacon(beacon)) == nil { 
    print("THING WAS SET TO 0 THIS SHOULD ONLY HAPPEN AT FIRST") 
    nearestBeaconsDictionary[keyForBeacon(beacon)] = 0 
} 
+0

Я тебя люблю. Я полностью забыл, что каждый объект CLBeacon был другим, даже если он был тем же самым маяком. Вы не представляете, как много усилий ушло на это. Ты спас мою ЖИЗНЬ !!!! – jonathanlv7

Смежные вопросы