EXC_BAD_ACCESS 点击 UISearchBar 三次出错

32

我正在尝试将搜索栏作为UICollectionViewReusableView实现在UICollectionView中。

这样,我就不是使用UISearchController了,而是改变collectionview的数据源。

在我的自定义布局中,我是这样添加搜索栏的:

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是实现了UISearchBarDelegate协议的UICollectionViewController。
代理在searchBar变量的didSet中设置。这些是我的代理。
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错误:

EXC_BAD_ACCESS (code=1, address=0x14ac0beb8)

我尝试打开启用Zombie对象,但没有提供任何信息。 我还尝试了为僵尸对象进行分析,但只是崩溃而没有任何明显的信息。

请帮我解决这个错误或给我进一步的调试说明。

编辑1:

以下是在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: 我创建了一个独立的项目,出现了这个错误。只需运行该项目并点击/取消搜索栏几次即可。

下载项目

视频:

Short gif showing crash

故障报告:rdar://problem/21673802


@Buster 控制台没有输出 - Phil Niedertscheider
1
从回溯信息来看,这似乎是UIResponder链中的一个错误。我还在调查中。 - JAL
2
离题了,但这是找到这些崩溃原因的好方法。http://natashatherobot.com/xcode-debugging-trick/ - DogCoffee
1
@JAL 实际上是的,他们昨晚要求我用iOS 9测试一下。我会试一试。 - Phil Niedertscheider
2
@JAL 好的,他们关闭了错误报告,并告诉我们升级到iOS 9是解决方案。我对这个答案不满意,但无论如何。 - Phil Niedertscheider
显示剩余24条评论
2个回答

1
我向苹果提交了一个错误报告,他们回复说:

苹果开发者关系

感谢您的更新。升级是解决方案。

我们正在关闭这个错误报告。

如果您对此问题的解决有疑问,请在您的错误报告中更新相关信息。

请确保定期检查新的苹果发布以获取可能影响此问题的任何更新。

基本上,由于即将发布iOS 9,他们现在不关心这个问题。
我问了如何保持与iOS 8兼容的正确方法,并且错误报告仍然处于打开状态。让我们等待并观察!

苹果有回复你关于在iOS 8上修复这个问题吗? - JAL
1
不,他们没有。它被标记为一个未解决的错误报告,并且问题内部消息的顺序是错误的,我认为有些地方出了问题。 - Phil Niedertscheider
我没有。你想让我加上吗? - Phil Niedertscheider
好的,请!这将有助于其他遇到相同问题的开发人员。谢谢。 - JAL
1
Openradar: rdar://problem/21673802 - Phil Niedertscheider
显示剩余2条评论

1
我在iOS 8中想出了一个解决方法。我发现只有当我的补充视图的kind字符串是Swift字符串时才会崩溃。如果我使用一个Objective-C字符串桥接到Swift,就不会崩溃。我尝试了在Swift中显式创建NSString甚至尝试创建一个CFString并进行桥接,但这两个尝试都没有成功。
为了轻松验证这一点,请将TeacherSearchbarIdentifier更改为UIKit中的Objective-C字符串,例如UICollectionElementKindSectionHeader
一个更严格的解决方法涉及为您的用例创建Objective-C字符串并将其暴露给Swift。例如:
// MyElementKinds.h

@import Foundation;

FOUNDATION_EXPORT NSString *const TeacherSearchbarIdentifier;

// MyElementKinds.m

#import "MyElementKinds.h"

NSString *const TeacherSearchbarIdentifier = @"TeacherSearchbarIdentifier";

谢谢你的回答。我最终会去看一下。 - Phil Niedertscheider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接