I have this code here:
@objc func buttonTapped(sender: DateFieldButton) {
// Thread 1: EXC_BAD_ACCESS (code=1, address=0xfffe) here
NotificationCenter.default.post(name: .dateFieldTapped, object: nil, userInfo: [0 : sender.pattern])
}
extension Notification.Name {
static let dateFieldTapped = Notification.Name("dateFieldTapped")
}
Had button.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
DeviceFieldButton
is just a subclass of UIButton
, with an additional field of pattern
. On a physical device (iPhone X on iOS 13.2), EXC_BAD_ACCESS does not occur. It is only replicable in the Simulator. Have cleaned project multiple times with same observations.
Edit:
Back trace:
libobjc.A.dylib`objc_retain:
0x7fff50b51c60 <+0>: testq %rdi, %rdi
0x7fff50b51c63 <+3>: je 0x7fff50b51c81 ; <+33>
0x7fff50b51c65 <+5>: js 0x7fff50b51c83 ; <+35>
-> 0x7fff50b51c67 <+7>: movq (%rdi), %rax
0x7fff50b51c6a <+10>: testb $0x4, 0x20(%rax)
0x7fff50b51c6e <+14>: jne 0x7fff50b51c88 ; objc_object::sidetable_retain()
0x7fff50b51c74 <+20>: movq 0x3908fee5(%rip), %rsi ; "retain"
0x7fff50b51c7b <+27>: jmpq *0x36ced19f(%rip) ; (void *)0x00007fff50b37400: objc_msgSend
0x7fff50b51c81 <+33>: xorl %edi, %edi
0x7fff50b51c83 <+35>: movq %rdi, %rax
0x7fff50b51c86 <+38>: retq
0x7fff50b51c87 <+39>: nop
Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:]:
0x7fff2590ddf0 <+0>: testq %rdx, %rdx
0x7fff2590ddf3 <+3>: je 0x7fff2590de44 ; <+84>
0x7fff2590ddf5 <+5>: pushq %rbp
0x7fff2590ddf6 <+6>: movq %rsp, %rbp
0x7fff2590ddf9 <+9>: pushq %r15
0x7fff2590ddfb <+11>: pushq %r14
0x7fff2590ddfd <+13>: pushq %rbx
0x7fff2590ddfe <+14>: pushq %rax
0x7fff2590ddff <+15>: movq %rdi, %r14
0x7fff2590de02 <+18>: movq 0x62206d9f(%rip), %rdi ; (void *)0x00007fff87b1d538: NSConcreteNotification
0x7fff2590de09 <+25>: movq 0x622003a8(%rip), %rsi ; "newTempNotificationWithName:object:userInfo:"
0x7fff2590de10 <+32>: movq 0x5b06b749(%rip), %r15 ; (void *)0x00007fff50b37400: objc_msgSend
0x7fff2590de17 <+39>: callq *%r15
0x7fff2590de1a <+42>: movq %rax, %rbx
0x7fff2590de1d <+45>: movq 0x8(%r14), %rdi
0x7fff2590de21 <+49>: movq %rax, %rsi
0x7fff2590de24 <+52>: xorl %edx, %edx
0x7fff2590de26 <+54>: callq 0x7fff25ae65d8 ; symbol stub for: _CFXNotificationPost
-> 0x7fff2590de2b <+59>: movq 0x6220038e(%rip), %rsi ; "recycle"
0x7fff2590de32 <+66>: movq %rbx, %rdi
0x7fff2590de35 <+69>: movq %r15, %rax
0x7fff2590de38 <+72>: addq $0x8, %rsp
0x7fff2590de3c <+76>: popq %rbx
0x7fff2590de3d <+77>: popq %r14
0x7fff2590de3f <+79>: popq %r15
0x7fff2590de41 <+81>: popq %rbp
0x7fff2590de42 <+82>: jmpq *%rax
0x7fff2590de44 <+84>: retq
DeviceFieldButton
:
class DateFieldButton: UIButton {
var pattern = String()
override var isSelected: Bool {
didSet {
if #available(iOS 13.0, *) {
backgroundColor = isHighlighted ? .highlightKeyboardColor : .keyboardColor
} else {
backgroundColor = isHighlighted ? .highlightLightKeyboard : .lightKeyboard
}
}
}
override var isHighlighted: Bool {
didSet {
if #available(iOS 13.0, *) {
backgroundColor = isHighlighted ? .highlightKeyboardColor : .keyboardColor
} else {
backgroundColor = isHighlighted ? .highlightLightKeyboard : .darkKeyboard
}
}
}
}
Usage:
let button = DateFieldButton(type: .custom)
button.layer.cornerRadius = 10
dateFormatter.dateFormat = pattern
let realPattern = dateFormatter.string(from: Date())
button.setTitle(realPattern, for: .normal)
button.titleLabel?.text = realPattern
button.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
if #available(iOS 13, *) {
button.setTitleColor(.blackAndWhite, for: .normal)
}
else {
button.setTitleColor(.black, for: .normal)
}
button.pattern = pattern
button.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
after a day of debugging, I have found the issue to the crash.
Previously I was using this for the receiving end, I was using this:
NotificationCenter.default.addObserver(self, selector: #selector(dateButtonTapped(_:for:)), name: .dateFieldTapped, object: nil)
@objc func dateButtonTapped(_ sender: Notification, for event: UIEvent) {
}
This causes the crash in the Simulator, which does not occur, if the for
parameter is removed, which was a left over from another method which I copied over due to laziness.
NotificationCenter.default.addObserver(self, selector: #selector(dateButtonTapped(_:)), name: .dateFieldTapped, object: nil)
@objc func dateButtonTapped(_ sender: Notification) {
}
So, I'm answering my own question, in case others in the future stumble across with the same issue.
By the way, thanks to @Philip Mills in the above comment. That made me look into the receiving end instead of focusing on the posting end.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.