EXC_BAD_ACCESS трижды нажав на панель пользователя
Я пытаюсь реализовать панель поиска в UICollectionView как UICollectionViewReusableView
Таким образом, я не использую UISearchController, но меняю источник данных в представлении коллекции
В моем собственном макете я добавляю панель поиска следующим образом:
override func prepareLayout() {
super.prepareLayout()
var searchBarAttributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: TeacherSearchbarIdentifier, withIndexPath: NSIndexPath(forItem: 0, inSection: 0))
searchBarAttributes.frame = CGRectMake(0, 0, collectionViewContentSize().width, 44)
searchBarAttributes.zIndex = 100
miscAttributes.append(searchBarAttributes)
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var attributes = [UICollectionViewLayoutAttributes]()
for (idx, attr) in enumerate(miscAttributes) {
if CGRectIntersection(rect, attr.frame) != CGRectNull {
attributes.append(attr)
}
}
return attributes
}
Я устанавливаю делегата следующим образом:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
var view = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: kind, forIndexPath: indexPath) as! UICollectionReusableView
if kind == TeacherSearchbarIdentifier {
controller.searchBar = (view as! TeacherSearchView).searchBar
return view
}
}
Переменная controller
это UICollectionViewController, который реализует UISearchBarDelegate
протокол
Делегат устанавливается в didSet переменной searchBar. Это мои делегаты:
override func scrollViewDidScroll(scrollView: UIScrollView) {
self.view.endEditing(true)
}
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
searchBar.setShowsCancelButton(true, animated: true)
return true
}
func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
searchBar.setShowsCancelButton(false, animated: true)
searchBar.resignFirstResponder()
return true
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchBar.setShowsCancelButton(false, animated: true)
searchBar.resignFirstResponder()
}
Теперь моя проблема!
Когда я нажимаю на строку поиска, появляется клавиатура. Если я нажимаю кнопку отмены или прокрутки, он исчезает. Так же, как я этого хочу. Это также работает во второй раз.
НО!
Если я сделаю это в третий раз, я получу EXC_BAD_ACCESS:
Я пытался включить Enabling Zombie Objects, но никакой информации предоставлено не было. Я также попробовал профилирование для объектов зомби, оно просто вылетает без какой-либо заметной информации.
Пожалуйста, помогите мне, как я могу решить эту ошибку, или дайте мне дальнейшие инструкции по отладке.
РЕДАКТИРОВАТЬ 1:
Вот вывод из bt all
в отладчике lldb:
* thread #1: tid = 0x228fc, 0x000000019502fbd0 libobjc.A.dylib`objc_msgSend + 16, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1cda8beb8)
frame #0: 0x000000019502fbd0 libobjc.A.dylib`objc_msgSend + 16
frame #1: 0x000000018328b2f4 CoreFoundation`-[__NSDictionaryM objectForKey:] + 84
frame #2: 0x00000001884a21b8 UIKit`-[UICollectionView _visibleViewDictForElementCategory:elementKind:] + 96
frame #3: 0x0000000187ff6644 UIKit`-[UICollectionView _indexPathForView:ofType:] + 160
frame #4: 0x000000018849c3dc UIKit`-[UICollectionView _setIsAncestorOfFirstResponder:] + 792
frame #5: 0x0000000187ed9418 UIKit`+[UIView(Internal) _setIsResponderAncestorOfFirstResponder:startingAtFirstResponder:] + 164
frame #6: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #7: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #8: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #9: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #10: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #11: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #12: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #13: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #14: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #15: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #16: 0x0000000187ed925c UIKit`-[UIResponder(Static) _setFirstResponder:] + 56
frame #17: 0x0000000187f1b194 UIKit`-[UITextField _becomeFirstResponder] + 60
frame #18: 0x000000018800f300 UIKit`-[UISearchBarTextField _becomeFirstResponder] + 108
frame #19: 0x0000000187e9ad28 UIKit`-[UIResponder becomeFirstResponder] + 392
frame #20: 0x0000000187e9b0ac UIKit`-[UIView(Hierarchy) becomeFirstResponder] + 124
frame #21: 0x0000000187f19de4 UIKit`-[UITextField becomeFirstResponder] + 68
frame #22: 0x0000000187fc9fc4 UIKit`-[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 200
frame #23: 0x0000000187fc962c UIKit`-[UITextInteractionAssistant(UITextInteractionAssistant_Internal) oneFingerTap:] + 1736
frame #24: 0x0000000187faf070 UIKit`_UIGestureRecognizerSendActions + 276
frame #25: 0x0000000187e486b4 UIKit`-[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 580
frame #26: 0x00000001882b938c UIKit`___UIGestureRecognizerUpdate_block_invoke662 + 60
frame #27: 0x0000000187e0c418 UIKit`_UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 292
frame #28: 0x0000000187e0a7c4 UIKit`_UIGestureRecognizerUpdate + 2504
frame #29: 0x0000000187e4682c UIKit`-[UIWindow _sendGesturesForEvent:] + 1044
frame #30: 0x0000000187e45ee4 UIKit`-[UIWindow sendEvent:] + 660
frame #31: 0x0000000187e19120 UIKit`-[UIApplication sendEvent:] + 264
frame #32: 0x00000001880ba2b8 UIKit`_UIApplicationHandleEventFromQueueEvent + 15424
frame #33: 0x0000000187e17634 UIKit`_UIApplicationHandleEventQueue + 1716
frame #34: 0x0000000183358240 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #35: 0x00000001833574e4 CoreFoundation`__CFRunLoopDoSources0 + 264
frame #36: 0x0000000183355594 CoreFoundation`__CFRunLoopRun + 712
frame #37: 0x00000001832812d4 CoreFoundation`CFRunLoopRunSpecific + 396
frame #38: 0x000000018ccdf6fc GraphicsServices`GSEventRunModal + 168
frame #39: 0x0000000187e7ef40 UIKit`UIApplicationMain + 1488
* frame #40: 0x00000001000f0798 My-Project`main + 164 at AppDelegate.swift:14
frame #41: 0x00000001956c6a08 libdyld.dylib`start + 4
thread #2: tid = 0x22939, 0x00000001957c4c24 libsystem_kernel.dylib`kevent64 + 8, queue = 'com.apple.libdispatch-manager'
frame #0: 0x00000001957c4c24 libsystem_kernel.dylib`kevent64 + 8
frame #1: 0x000000010083a588 libdispatch.dylib`_dispatch_mgr_invoke + 276
frame #2: 0x000000010082b09c libdispatch.dylib`_dispatch_mgr_thread + 52
thread #8: tid = 0x229d9, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #7: tid = 0x229da, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #9: tid = 0x229df, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #10: tid = 0x229e1, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #11: tid = 0x229e2, 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #0: 0x00000001957dfc78 libsystem_kernel.dylib`__workq_kernreturn + 8
frame #1: 0x00000001958792dc libsystem_pthread.dylib`_pthread_wqthread + 992
thread #12: tid = 0x229e3, 0x00000001957c4e0c libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.NSURLConnectionLoader'
frame #0: 0x00000001957c4e0c libsystem_kernel.dylib`mach_msg_trap + 8
frame #1: 0x00000001957c4c88 libsystem_kernel.dylib`mach_msg + 72
frame #2: 0x0000000183357724 CoreFoundation`__CFRunLoopServiceMachPort + 200
frame #3: 0x0000000183355678 CoreFoundation`__CFRunLoopRun + 940
frame #4: 0x00000001832812d4 CoreFoundation`CFRunLoopRunSpecific + 396
frame #5: 0x0000000182d5e594 CFNetwork`+[NSURLConnection(Loader) _resourceLoadLoop:] + 440
frame #6: 0x00000001842a1db8 Foundation`__NSThread__main__ + 1072
frame #7: 0x000000019587bdc8 libsystem_pthread.dylib`_pthread_body + 164
frame #8: 0x000000019587bd24 libsystem_pthread.dylib`_pthread_start + 160
thread #13: tid = 0x229e6, 0x00000001957df498 libsystem_kernel.dylib`__select + 8, name = 'com.apple.CFSocket.private'
frame #0: 0x00000001957df498 libsystem_kernel.dylib`__select + 8
frame #1: 0x000000018335d128 CoreFoundation`__CFSocketManager + 672
frame #2: 0x000000019587bdc8 libsystem_pthread.dylib`_pthread_body + 164
frame #3: 0x000000019587bd24 libsystem_pthread.dylib`_pthread_start + 160
РЕДАКТИРОВАТЬ 2: я создал автономный проект, который производит эту ошибку. Просто запустите проект и нажмите / отмените панель поиска несколько раз.
Видео:
Отчет об ошибке: rdar: // problem / 21673802
2 ответа
Я нашел обходной путь для этого в iOS 8. Я обнаружил, что сбой произошел только если kind
Строка моего дополнительного представления была строкой Swift. Когда я использовал строку Objective-C, соединенную со Swift, не было сбоев. Я попробовал очевидную идею создания NSString
явно в Swift и даже пытался создать CFString
в Свифте и преодолении этого. Однако ни одно из этих усилий не было успешным.
Чтобы легко это проверить, попробуйте изменить TeacherSearchbarIdentifier
на строку Objective-C из UIKit, как UICollectionElementKindSectionHeader
,
Более строгий обходной путь будет включать создание строк Objective-C для вашего варианта использования и предоставление их Swift. В качестве примера:
// MyElementKinds.h
@import Foundation;
FOUNDATION_EXPORT NSString *const TeacherSearchbarIdentifier;
// MyElementKinds.m
#import "MyElementKinds.h"
NSString *const TeacherSearchbarIdentifier = @"TeacherSearchbarIdentifier";
Я отправил сообщение об ошибке в Apple, и они сказали это:
Отношения Apple с разработчиками
Спасибо за обновление. Обновление является решением тогда.
Мы закрываем этот отчет об ошибке.
Если у вас есть вопросы, касающиеся решения этой проблемы, обновите отчет об ошибке с этой информацией.
Обязательно регулярно проверяйте новые выпуски Apple на наличие обновлений, которые могут повлиять на эту проблему.
По сути, они не заботятся об этой проблеме прямо сейчас из-за их предстоящего выпуска iOS 9
Я спросил, как правильно сохранить совместимость с iOS 8, и отчет об ошибке все еще открыт. Давайте подождем и посмотрим!