Pregunta EXC_BAD_ACCESS tocando uisearchbar tres veces


Estoy intentando implementar una barra de búsqueda en UICollectionView como UICollectionViewReusableView

De esta manera, no estoy usando un UISearchController pero estoy cambiando el origen de datos de la colección

En mi diseño personalizado, agrego la barra de búsqueda de esta manera:

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
}

Estoy configurando al delegado así:

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
    }
}

La variable controller es el UICollectionViewController que implementa el UISearchBarDelegate Protocolo

El delegado se establece en didSet de la variable searchBar. Estos son mis delegados:

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()
}

¡Ahora mi problema!

Cuando toco en la barra de búsqueda, aparece el teclado. Si presiono el botón de cancelar o desplazarme, desaparece. Justo como yo quiero. Esto también funciona por segunda vez.

¡PERO!

Si hago esto por tercera vez, obtengo un EXC_BAD_ACCESS:

EXC_BAD_ACCESS (code=1, address=0x14ac0beb8)

Traté de activar Enabling Zombie Objects, pero no se proporcionó información. También traté de crear perfiles para Zombie Objects, simplemente se bloquea sin ninguna información notable.

Ayúdenme a resolver cómo puedo resolver este error o darme más instrucciones de depuración.

EDIT 1:

Aquí está el resultado de bt all en el depurador 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

EDICION 2: Creé un proyecto independiente que produce este error. Simplemente ejecute el proyecto y toque / cancele la barra de búsqueda varias veces.

Descargar Proyecto

Vídeo:

Short gif showing crash

Informe de error: rdar: // problema / 21673802


32
2018-06-28 10:37


origen


Respuestas:


Se me ocurrió una solución para esto en iOS 8. Descubrí que el bloqueo solo se producía si kind La secuencia de mi vista suplementaria era una cadena Swift. No se produjo un bloqueo cuando utilicé una cadena Objective-C unida a Swift. Intenté la idea obvia de crear un NSString explícitamente en Swift e incluso intentó crear un CFString en Swift y uniendo eso. Sin embargo, ninguno de esos esfuerzos fue exitoso.

Para verificar esto fácilmente, intente cambiar TeacherSearchbarIdentifier a una cadena Objective-C de UIKit como UICollectionElementKindSectionHeader.

Una solución más rigurosa implicaría crear cadenas de Objective-C para su caso de uso y exponerlas a Swift. Como ejemplo:

// MyElementKinds.h

@import Foundation;

FOUNDATION_EXPORT NSString *const TeacherSearchbarIdentifier;
// MyElementKinds.m

#import "MyElementKinds.h"

NSString *const TeacherSearchbarIdentifier = @"TeacherSearchbarIdentifier";

1
2018-04-25 00:32



Le envié un informe de error a Apple, y dijeron esto:

Relaciones con desarrolladores de Apple

Gracias por la actualización. La actualización es la solución entonces.

Estamos cerrando este informe de errores.

Si tiene preguntas sobre la resolución de este problema, por favor   actualiza tu informe de error con esa información.

Por favor, asegúrese de verificar regularmente los nuevos lanzamientos de Apple para cualquier actualización   eso podría afectar este problema

Básicamente no les importa este problema en este momento debido a su próximo lanzamiento de iOS 9

Le pregunté cuál es la forma correcta de mantener la compatibilidad con iOS 8 y el informe de fallas aún está abierto. ¡Vamos a esperar y ver!


1
2017-07-27 08:34