Я использую UITableView
, который использует ячейки с UITextField
в них, чтобы представить представление профиля, в котором пользователь может сохранить некоторую информацию о своей учетной записи.
В tableView(_:cellForRowAt:)
,в какой-то момент возможная ячейка устанавливается следующим образом:
...
else if indexPath.row == 5 {
var cell = tableView.dequeueReusableCell(withIdentifier: id) as? ProfileGeneralTableViewCell
...
// Some not related cell setup
...
cell?.saveHandler = { [weak self] text in
guard let self = self else { return }
if let account = self.account {
if account.address == nil {
self.account?.address = [Values(show: true, field: text)]
} else if let address = account.address {
if address.isEmpty {
self.account?.address = [Values(show: true, field: text)]
} else if let _ = self.account?.address?.first{
self.account?.address?[0].field = text
}
}
}
}
return cell!
}
Класс ячейки использует функцию делегата текстового поля для правильного сохранения данных, записанных в текстовом поле каждый раз, когда пользователь что-то вводит в него, используяsaveHandler
закрытие, введенное в tableView(_:cellForRowAt:)
, которое обновляет информацию об учетной записи:
extension ProfileGeneralTableViewCell: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text,
let textRange = Range(range, in: text) {
let updatedText = text.replacingCharacters(in: textRange,
with: string)
saveHandler?(updatedText)
}
return true
}
Описание моделей данных, вызывающих проблему:
struct Account: Codable {
var account: String
var id: String
var name: String
var surname: String
var email: Values?
var phone: [Values]?
var address: [Values]?
var title: Values?
var workPlace: Values?
var avatar: String?
var showComments: Bool?
var showNotes: Bool?
var subscriber: String?
var codes: [Code]?
var expires: String?
}
struct Values: Codable {
var show: Bool
var field: String
}
Thisчасть кода
if address.isEmpty {
self.account?.address = [Values(show: true, field: text)]
}
- это та, которая вызывает сбой приложения, но только по какой-то причине только в среде выпуска.Зная, что self.account?.address
- это пустой массив в начале, когда пользователь что-то печатает, во второй набранной букве происходит сбой приложения.Crashlytics дает этот маршрут трассировки:
Crashed: com.apple.main-thread
0 libswiftCore.dylib 0x2668646ec swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::incrementSlow(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) + 40
1 libswiftCore.dylib 0x266845dac _swift_retain_(swift::HeapObject*) + 104
2 libswiftCore.dylib 0x266845dac _swift_retain_(swift::HeapObject*) + 104
3 libswiftCore.dylib 0x26688a2e4 swift_bridgeObjectRetain + 52
4 LexUP Testing 0x100804bc4 outlined copy of Account? + 4314598340
5 LexUP Testing 0x10086c77c closure #5 in MyProfileViewController.tableView(_:cellForRowAt:) (<compiler-generated>)
6 LexUP Testing 0x10095b178 ProfileGeneralTableViewCell.textField(_:shouldChangeCharactersIn:replacementString:) + 144 (ProfileGeneralTableViewCell.swift:144)
7 LexUP Testing 0x10095b238 @objc ProfileGeneralTableViewCell.textField(_:shouldChangeCharactersIn:replacementString:) (<compiler-generated>)
8 UIKitCore 0x26577a640 -[UITextField keyboardInput:shouldInsertText:isMarkedText:] + 376
9 UIKitCore 0x2652bd9b8 -[UIKeyboardImpl callShouldInsertText:] + 164
10 UIKitCore 0x2652cbb10 -[UIKeyboardImpl addInputEvent:executionContext:] + 824
11 UIKitCore 0x2652cb7c4 __81-[UIKeyboardImpl addInputString:withFlags:withInputManagerHint:executionContext:]_block_invoke + 60
12 UIKitCore 0x2652fc5d0 -[UIKeyboardTaskExecutionContext returnExecutionToParentWithInfo:] + 160
13 UIKitCore 0x2652cb67c -[UIKeyboardImpl addInputString:withFlags:withInputManagerHint:executionContext:] + 456
14 UIKitCore 0x2652dd07c -[UIKeyboardImpl handleKeyWithString:forKeyEvent:executionContext:] + 764
15 UIKitCore 0x2652dcb8c -[UIKeyboardImpl handleKeyEvent:executionContext:] + 1808
16 UIKitCore 0x2652dc300 -[UIKeyboardImpl _handleKeyEvent:executionContext:] + 492
17 UIKitCore 0x2652502f4 -[UIKeyboardLayoutStar completeRetestForTouchUp:timestamp:interval:executionContext:] + 4764
18 UIKitCore 0x2652e8cb8 __45-[UIKeyboardLayout touchUpTaskForTouchState:]_block_invoke + 232
19 UIKitCore 0x2652e8f14 __28-[UIKeyboardLayout touchUp:]_block_invoke + 108
20 UIKitCore 0x2652fe570 -[UIKeyboardTaskEntry execute:] + 188
21 UIKitCore 0x2652fcd14 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 384
22 UIKitCore 0x2652e7010 -[UIKBTouchOrderedTaskList executeTasksInView:withBlock:] + 268
23 UIKitCore 0x2652eaa78 -[UIKeyboardLayout _enumerateDeferredTouchUUIDs:withBlock:] + 392
24 UIKitCore 0x2652ed9b8 __88-[UIKeyboardLayout recognizer:releaseTouchToLayoutWithId:startPoint:endPoint:whenReady:]_block_invoke + 1016
25 libdispatch.dylib 0x2389c87d4 _dispatch_client_callout + 16
26 libdispatch.dylib 0x238976ce8 _dispatch_async_and_wait_invoke + 92
27 libdispatch.dylib 0x2389c87d4 _dispatch_client_callout + 16
28 libdispatch.dylib 0x238976004 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1068
29 CoreFoundation 0x238f19c1c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
30 CoreFoundation 0x238f14b54 __CFRunLoopRun + 1924
31 CoreFoundation 0x238f140b0 CFRunLoopRunSpecific + 436
32 GraphicsServices 0x23b11479c GSEventRunModal + 104
33 UIKitCore 0x265484978 UIApplicationMain + 212
34 LexUP Testing 0x1007fe75c main + 28 (FBComment.swift:28)
35 libdyld.dylib 0x2389d98e0 start + 4