Проблема с передачей по значению против передачи по ссылке в Swift?
Я новичок в Swift, но не новичок в iOS dev. У меня возникла проблема, которая, по моему мнению, вызвана передачей по стоимости.
Ниже код находится в VC и отлично работает при нажатии каждой кнопки, то есть каждая кнопка меняет фон, чтобы показать, выбрана она или нет.
button.isSelected = card.isChosen // button is selected when the card is chosen
if button.isSelected {
button.setBackgroundColor(color: UIColor.darkGray, forState: UIControlState.selected)
}
У меня есть проблема в игровой логике, которая является структурой. Struct содержит массив типа Card, который на самом деле представляет собой просто колоду карт и отображается обратно на кнопки UIB. При касании карты (UIButton) в VC вызывается метод (выбрать карту) в Struct. Среди прочего, это действие будет переключаться, если карта выбрана путем установки card.isSelected =! Card.isSelected и отображается обратно в пользовательский интерфейс, чтобы указать, выбрана ли карта или нет. Пока все это прекрасно работает.
Когда выбрано 3 карты, это вызывает некоторую логику совпадения, которая в настоящее время просто заглушена. Если совпадений не было, для каждой карты.isSelected устанавливается значение false, поэтому в пользовательском интерфейсе эти карты больше не будут отображаться выбранными. Это то, что не работает, и я не могу понять, почему. Я догадываюсь, что я делаю что-то не так, когда имею дело с передачей по значению, поскольку логический объект является структурой. После того, как выбраны 3 карты, и они не совпадают (они не будут совпадать, так как это только заглушка), для каждого card.isSelected должно быть установлено значение false, но они все еще показывают выбранные в пользовательском интерфейсе. Я установил точку останова в VC, и она показывает, что card.isSelected все еще установлено в true. VC имеет свойство setGame, которое имеет доступ к массиву карт. Вот соответствующий код... любая помощь приветствуется!
struct SetGame {
private(set) var cards = [Card]()
mutating public func chooseCard(at index: Int) {
//TODO: Assertion here for index being < cards.count
print("chooseCard(at index: \(index)")
cards[index].isChosen = !cards[index].isChosen // toggle isChosen when card is selected
if !cards[index].isMatched && cards[index].isChosen {
//print("Card not matched, so we're good to go...")
for var card in cards {
if card.isChosen {
matchingCards.append(card)
// see if we have enough cards to match
if matchingCards.count > 2 {
//TODO: Need to call match logic here and set each matched card to .isMatched = true if matched
if card.isMatched {
print("Yay, matched!")
} else {
print("Card is not matched, flipping back over")
/*** THIS LINE NOT REFLECTING IN THE UI! ***/
card.isChosen = !card.isChosen // flip the unmatched card back over
}
}
}
}
matchingCards.removeAll() // clear out all the cards from the matching
} else {
print("Card is either matched or being deselected...")
}
}
1 ответ
Ваша проблема в том, что Card
это struct
Итак, эта строка:
for var card in cards {
создает копию каждой карты в cards
поэтому установка каких-либо свойств для этой копии не изменит карту в вашем cards
массив.
Чтобы это исправить, обведите indices
массива и ссылаются на карты как cards[idx]
:
struct SetGame {
private(set) var cards = [Card]()
mutating public func chooseCard(at index: Int) {
//TODO: Assertion here for index being < cards.count
print("chooseCard(at index: \(index)")
cards[index].isChosen = !cards[index].isChosen // toggle isChosen when card is selected
if !cards[index].isMatched && cards[index].isChosen {
//print("Card not matched, so we're good to go...")
for idx in cards.indices {
if cards[idx].isChosen {
matchingCards.append(cards[idx])
// see if we have enough cards to match
if matchingCards.count > 2 {
//TODO: Need to call match logic here and set each matched card to .isMatched = true if matched
if cards[idx].isMatched {
print("Yay, matched!")
} else {
print("Card is not matched, flipping back over")
/*** THIS LINE NOT REFLECTING IN THE UI! ***/
cards[idx].isChosen = !cards[idx].isChosen // flip the unmatched card back over
}
}
}
}
matchingCards.removeAll() // clear out all the cards from the matching
} else {
print("Card is either matched or being deselected...")
}
}
или рассмотреть вопрос о создании Card
class
так что когда вы имеете в виду Card
Вы знаете, что имеете в виду один и тот же объект.