gpt4 book ai didi

ios App 在解除分配 UIView 子类实例时崩溃

转载 作者:可可西里 更新时间:2023-11-01 06:10:15 24 4
gpt4 key购买 nike

我使用 CocoaTouch 和 ARC native 构建的应用程序在取消分配 UIView 子类实例时崩溃。

这是崩溃日志。

OS Version:      iOS 6.1.3 (10B329)

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000008
Crashed Thread: 0

0: 0x39de65b0 libobjc.A.dylib objc_msgSend + 16
1: 0x31edb694 CoreFoundation -[NSArray makeObjectsPerformSelector:] + 300
2: 0x33d8c57a UIKit -[UIView(UIViewGestures) removeAllGestureRecognizers] + 146
3: 0x33d8c144 UIKit -[UIView dealloc] + 440
4: 0x00240b36 MyApp -[StandardPanelView .cxx_destruct](self=0x20acba30, _cmd=0x00240985) + 434 at StandardPanelView.m:139
5: 0x39deaf3c libobjc.A.dylib object_cxxDestructFromClass(objc_object*, objc_class*) + 56
6: 0x39de80d2 libobjc.A.dylib objc_destructInstance + 34
7: 0x39de83a6 libobjc.A.dylib object_dispose + 14
8: 0x33d8c26a UIKit -[UIView dealloc] + 734
9: 0x0022aa14 MyApp -[StandardPanelView dealloc](self=0x20acba30, _cmd=0x379f1a66) + 156 at StandardPanelView.m:205
10: 0x39de8488 libobjc.A.dylib (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 168
11: 0x31e98440 CoreFoundation _CFAutoreleasePoolPop + 16
12: 0x31f28f40 CoreFoundation __CFRunLoopRun + 1296
13: 0x31e9bebc CoreFoundation CFRunLoopRunSpecific + 356
14: 0x31e9bd48 CoreFoundation CFRunLoopRunInMode + 104
15: 0x35a502ea GraphicsServices GSEventRunModal + 74
16: 0x33db1300 UIKit UIApplicationMain + 1120
17: 0x00113c50 MyApp main(argc=1, argv=0x2fd3ed30) + 140 at main.m:23

问题是:

  1. 可能设置错误导致对 [UIView(UIViewGestures) removeAllGestureRecognizers] 的内部调用崩溃。一种理论认为手势数组中的某些手势已经在其他地方释放。
  2. 当 UIView 包含 subview 时,释放过程的顺序如何?

一些额外的背景信息:

  1. 崩溃发生了,但没有准确的方法来重现它。
  2. StandardPanelView 实例作为属于其 subview 的手势的委托(delegate)。
  3. 我们在 StandardPanelView 实例上使用 flyweight,即缓存和回收。

提前感谢您提供有关此崩溃如何发生的任何提示。

最佳答案

我的第一印象是您可能正在尝试访问刚刚解除分配的 StandardPanelView。

  • What could be set wrong that makes the internal call to [UIView(UIViewGestures) removeAllGestureRecognizers] crash. One theory is that some gesture in the gestures array is deallocated already somewhere else.

这不会是因为 UIGestureRecognizer 被释放了。 UIView 强烈地将 UIGestureRecognizers 保存在 NSArray 中。当它们仍在数组中时,它们不会被释放。

但是,UIGestureRecognizer 的委托(delegate) 可能已被释放。这只是一个(分配)属性,意味着它不是强持有的,如果委托(delegate)被释放,它将成为一个悬空指针。因此,如果在 [NSArray makeObjectsPerformSelector:] 中使用了委托(delegate),则可能会发生这种情况。

  • When a UIView contains subviews, how is the sequence of deallocation process?

对象从“ parent ”释放到“ child ”,即。 super View 被释放,然后是 subview ,然后是手势识别器。 (虽然 subview 是否在手势识别器之前被释放是一个实现细节,所以你可能不应该依赖它)。

我们可以在一个简单的示例 Controller 中看到这一点:

// The UIView that will be used as the main view// This is the superview@interface MyView : UIView@end@implementation MyView- (void)dealloc {    NSLog(@"Dealloc MyView");}@end// This view will be put inside MyView to be used as a subview@interface MySubview : UIView@end@implementation MySubview- (void)dealloc {    NSLog(@"Dealloc MySubview");}@end// This is the gesture recognizer that we will use// We will give one to each view, and see when it is deallocated@interface MyGestureRecognizer : UIGestureRecognizer@property (nonatomic, copy) NSString *tag;@end@implementation MyGestureRecognizer@synthesize tag;-(void)dealloc {    NSLog(@"Dealloc MyGestureRecognizer tag: %@", tag);}@end// Just a test view controller that we will push on/pop off the screen to take a look at the deallocations@interface TestViewController : UIViewController @end@implementation TestViewController- (void)loadView {    self.view = [[MyView alloc] init];    MyGestureRecognizer *recognizer = [[MyGestureRecognizer alloc] initWithTarget:self action:@selector(doStuff)];    recognizer.tag = @"MyViewGestureRecognizer";    recognizer.delegate = self;    [self.view addGestureRecognizer:recognizer];}- (void)viewDidLoad {    [super viewDidLoad];    MySubview *subview = [[MySubview alloc] init];    MyGestureRecognizer *recognizer = [[MyGestureRecognizer alloc] initWithTarget:self action:@selector(doStuff)];    recognizer.tag = @"MySubviewGestureRecognizer";    recognizer.delegate = self;    [subview addGestureRecognizer:recognizer];    [self.view addSubview:subview];}- (void)doStuff {  // we don't actually care what it does}@end

我们所做的就是添加 MyView 作为 TestViewController 的主视图,然后在 MyView 中添加一个 MySubview。我们还将 MyGestureRecognizer 附加到每个 View 。

当我们将它推离屏幕时,我们的日志输出显示:

Dealloc TestViewControllerDealloc MyViewDealloc MySubviewDealloc MyGestureRecognizer tag: MySubviewGestureRecognizerDealloc MyGestureRecognizer tag: MyViewGestureRecognizer

很抱歉,回答太长了...您发布它已经大约 3 个月了,所以也许您已经解决了这个问题,但如果其他人偶然发现了这个答案,我希望它能有所帮助。

关于ios App 在解除分配 UIView 子类实例时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18398069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com