Здравствуйте, я использую этот код while true {
AudioServicesPlaySystemSound(SystemSoundID(1520))
} для создания бесконечной вибрации. При нажатии на кнопку приложение начинает вибрировать но через какое-то время вылетает и выдаёт ошибку The app “massegere1” on iPhone (Егор) quit unexpectedly.
Message from debugger: Terminated due to memory issue как её исправить. И ещё один вопрос: как остановить эту вибрацию при повторном нажатии на кнопку?
Помогите пожалуйста
Заранее спасибо
Память и цикл while true в Свифт
Здравствуйте.
Нужно быть очень осторожным с бесконечными циклами. В вашем случае, вы каждую итерацию даёте устройству команду на проигрывание звука - итерации проходят очень быстро, проигрываемых одновременно звуков становится очень много, можете посмотреть в xCode, как увеличивается потребление памяти вашим приложением)
Лучше использовать метод AudioServicesPlaySystemSoundWithCompletion, который может выполнять код после завершения своей работы - и в нём повторно запустить вибрацию, если это необходимо.
А чтобы включать/выключать вибрацию по кнопке, хранить состояние в переменной типа Bool, например так:
private var vibroEnabled = false
@IBAction func buttonAction(_ sender: UIButton) {
vibroEnabled = !vibroEnabled
if vibroEnabled {
startVibration()
}
}
private func startVibration() {
AudioServicesPlaySystemSoundWithCompletion(SystemSoundID(1520)) {
if self.vibroEnabled {
self.startVibration()
}
}
}
Спасибо это и правда работает. Только я там воспроизвожу вибрацию.
У меня шесть кнопок с вибрацией не подскажите как сделать так чтоб при работе одной кнопки можно было переключится на другую и предидущая полностью остановила свой цикл?
В данный момент при работе одной кнопки я нажимаю на вторую и да она начинает выполнять свой код но чтоб полностью остановить вибрацию надо нажать сначала на вторую а затем уже на первую и только при этом вибрация полностью остановится
Храните у себя референс на нажатую кнопку и после нажатия на другуюу проверяйте этот референс, если он занят, то отключите соответствующую вибрацию, после чего запустите новую и в референс уже запишите новую кнопку.
Лучше всего в данном случае работать с енумом.
Создайте енум для ваших вибраций
enum Vinbration: Int {
case vibro1 = 1520
case vibro2 = ...
}
В вашем VC создайте переменную, которая будет хранить тип вибрации
var selectedVibro: Vibration?
Далее при нажатии на ваши кнопки, присваивайте этой переменной свой тип вибрации
func btn1Click() {
if selectedVibro == .vibro1 { selectedVibro = nil }
else selectedVibro = .vibro1
startVibration()
}
func btn2Click() {
if selectedVibro == .vibro2 { selectedVibro = nil }
else selectedVibro = .vibro2
startVibration()
}
Ну а дальше уже вызывайте метод который будет проверять нужно ли запускать вибрацию или остановиться. В этом методе уже будете проверять переменную selectedVibro
, что бы она не была пустая. А что бы получить нужный код вибрации selectedVibro.rawValue
.
func startVibration() {
guard let selectedVibro else { return }
AudioServicesPlaySystemSoundWithCompletion(SystemSoundID(selectedVibro.rawValue)) {
self.startVibration()
}
}
Тут очень много ошибок!
1 - let selectedVibro: Vibration? // Замени на var
2 - Вынеси функции btn1Click и startVibration за пределы экшена
3 - В функции btn1Click не хватает закрывающей скобки “}”
4 - В функции startVibration guard let vibrationType = selectedVibro else { return }