【问题标题】:Memory Management with Gesture Recognizer使用手势识别器进行内存管理
【发布时间】:2011-10-06 10:55:40
【问题描述】:

我的很多内存泄漏都来自这个识别滑动的代码。我究竟做错了什么?第一行是我认为正在泄漏的东西(使用仪器)。它被显示为许多错误的负责调用者 这是在 ViewDidLoad 中:

   UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRightAction:)];
    [(UISwipeGestureRecognizer *)swipeRight setNumberOfTouchesRequired:2];

    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    swipeRight.delegate = self;
    [webView addGestureRecognizer:swipeRight];

    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeftAction:)];
    [(UISwipeGestureRecognizer *)swipeLeft setNumberOfTouchesRequired:2];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    swipeLeft.delegate = self;
    [webView addGestureRecognizer:swipeLeft];

    // Do any additional setup after loading the view from its nib.

}

还有一个问题,什么会导致这里出现僵尸?我应该自动发布吗?

    AViewController *a = [[AViewController alloc]init];
[self.navigationController pushViewController:a animated:YES];

a.title =@"A View";
[a release];

更新 3:我运行工具来寻找错误的分配,并且通过一些密集的使用,我在这里得到了一个僵尸: 错误信息:An Objective-C message was sent to a deallocated object (zombie) at address: 0xf583270. 在仪器中,这就是我所看到的。 Instruments 突出显示了这条线,并且旁边有 100%。

AViewController *a = [[AViewController alloc]init];

【问题讨论】:

    标签: iphone ios xcode memory-management memory-leaks


    【解决方案1】:

    您正在分配/初始化 UISwipeGestureRecognizer(这使得您的工作是释放它),而不是在您的顶部代码中释放它,两次。将 [swipeRight release];[swipeLeft release]; 添加到 webview 后,您需要添加它们。

    【讨论】:

    • 似乎已经解决了大部分手势识别器泄漏问题。 :)
    • 还有一个问题,我在问题中添加了一些内容(代码在 cmets 中没有格式)
    • 如果你在a发布后不再使用它,就不应该出现僵尸问题..但是你应该在将它推送到navigationController堆栈之前设置标题..这可能会导致某种问题。
    • 我明白了。我应该这样做:[AViewController 发布];和[查看发布];或者只是第二个
    • 因为该对象的实例被称为a 这就是您发布的内容。所以你的发布电话很好(只要你不使用a,你没有在帖子中显示)。不过,我肯定会将a.title 线移到pushViewController: 线上方。
    【解决方案2】:

    将手势添加到您的视图后,对其调用release 方法,因为您添加的视图保留手势。

    如下图

     [webView addGestureRecognizer:swipeRight];  
        [swipeRight release];
    

    还有

     [webView addGestureRecognizer:swipeLeft];  
        [swipeLeft release];
    

    【讨论】:

    • 对,我认为应该可以解决它。我不知道我是怎么做到的。我现在正在测试:)
    【解决方案3】:

    object-c 中的内存管理肯定也需要一些时间来使用。我个人让运营为我处理一切。这意味着每次我分配一些东西时,我只是给它一个自动释放。操作系统会在需要时为我处理发布。唯一的问题是当您在同一范围内重用一个对象时,操作系统将向它发送太多版本并在您想要它之前释放内存。这是一个例子

    //This code will result in a memory crash
    CustomObject *coolThing = [[[CustomObject alloc] init] autorelease];
    [coolThing setAwesomeLevel:10];
    [array addObject:coolThing];
    
    [coolThing setAwesomeLevel:7];
    [array2 addObject:coolThing];
    

    你会使用

    //Working code
    CustomObject *coolThing = [[CustomObject alloc] init];
    [coolThing setAwesomeLevel:10];
    [array addObject:coolThing];
    
    [coolThing setAwesomeLevel:7];
    [array2 addObject:coolThing];
    
    [coolThing release];
    

    现在,要在您的代码中使用自动释放,您只需将它们添加到分配中即可。这就是您的代码泄漏的原因。当您将其添加到 webView 对象时,它会增加其保留帐户。当您离开该范围时,它的保留帐户为 2,但您只向它发送一次释放(它的保留将保持为 1,并且永远不会释放内存)。

    UISwipeGestureRecognizer *swipeRight = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRightAction:)] autorelease];
    [(UISwipeGestureRecognizer *)swipeRight setNumberOfTouchesRequired:2];
    
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    swipeRight.delegate = self;
    [webView addGestureRecognizer:swipeRight];
    
    UISwipeGestureRecognizer *swipeLeft = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeftAction:)] autorelease];
    [(UISwipeGestureRecognizer *)swipeLeft setNumberOfTouchesRequired:2];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    swipeLeft.delegate = self;
    [webView addGestureRecognizer:swipeLeft];
    

    如果您不想像这样使用自动释放,您只需在将手势添加到 webView 后添加一些释放即可。

    [swipeRight release];
    [swipeLeft release]
    

    【讨论】:

    • 很好的解释!我仍然习惯于内存管理,这很有帮助!
    • 顺便说一句,我在问题中添加了一些额外的代码。那会是我想使用自动释放的情况吗?如果我们快速来回切换,那不是问题吗?
    • 您添加的代码是正确的。添加自动发布和删除最终发布将产生相同的代码。这不是我上面提到的问题,因为您没有在同一范围内更改对象。我上面描述的问题非常少见,每当我提到自动释放功能时,我都会确保提及它。
    • 我会阅读苹果的内存管理指南。自动发布一切并不是学习/理解它的最佳方式。一旦你掌握了所有权的概念,它就不是问题了。
    • 谢谢。会做。我不打算自动发布所有内容,但是对于阅读链接的任何人来说,这里是:developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/…
    猜你喜欢
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多