簡體   English   中英

NSRecursiveLock解除分配

[英]NSRecursiveLock Deallocated

我有一個具有多個視圖控制器和ARC的iOS應用。 視圖控制器之一具有用於UIScrollViewUIPageControlIBOutlet 加載該視圖控制器后,該錯誤將顯示在控制台中:

*** -[NSRecursiveLock dealloc]: lock (<NSRecursiveLock: 0xcb88cb0> '(null)') 
deallocated while still in use

在嘗試解決此問題時,我為符號_NSLockError創建了符號斷點,並將模塊設置為Foundation。 現在,Xcode在線程1上的"0x12d2b58: pushl %ebp"上以斷點1.1中斷。

Foundation`_NSLockError:
-----------------------------------------------------
|> 0x12d2b58: pushl %ebp   <|Thread 1: breakpoint 1.1|
-----------------------------------------------------
0x12d2b59:  movl   %esp, %ebp
0x12d2b5b:  subl   $8, %esp
0x12d2b5e:  calll  0x12d2b63                 ; _NSLockError + 11
0x12d2b63:  popl   %eax
0x12d2b64:  leal   2118709(%eax), %eax
0x12d2b6a:  movl   %eax, (%esp)
0x12d2b6d:  calll  0x125689d                 ; NSLog
0x12d2b72:  addl   $8, %esp
0x12d2b75:  popl   %ebp
0x12d2b76:  ret  

這是我的應用程序中有問題的ViewController的代碼:

頭文件(.h):

#import <UIKit/UIKit.h>

@class AboutViewController;

@protocol AboutViewControllerDelegate

- (void)aboutViewControllerDidFinish:(AboutViewController *)controller;
@end

@interface AboutViewController : UIViewController<UIScrollViewDelegate>


@property (strong, nonatomic,retain) id <AboutViewControllerDelegate> delegate;
@property (nonatomic,strong,) IBOutlet UIScrollView *scrollView;
@property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
@property (nonatomic, strong) NSArray *imageArray;
@property(nonatomic, assign) IBOutlet UILabel *label;

- (IBAction)done:(id)sender; //returns back to main menu after a button is pressed

@end

實施文件(.m):

#import "AboutViewController.h"

@interface AboutViewController ()

@end

@implementation AboutViewController

@synthesize scrollView;
@synthesize pageControl;
@synthesize imageArray;

int page;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    //load the images for the scrollview in an array
    imageArray = [[NSArray alloc] initWithObjects:@"1.png", @"2.png", @"3.png", nil];

    for (int i = 0; i < [imageArray count]; i++ ) {
       int page = scrollView.contentOffset.x / scrollView.frame.size.width;

       CGRect frame;
       frame.origin.x = self.scrollView.frame.size.width * i;
       frame.origin.y = 0;
       frame.size = self.scrollView.frame.size;

        UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
        imageView.image = [UIImage imageNamed:[imageArray objectAtIndex:i]];
        [self.scrollView addSubview:imageView];

       NSLog (@"page %d",page);
        if (page==0) {
            self.label.text = [NSString stringWithFormat:@"%s","page1"];
        }


    }

    scrollView.contentSize = CGSizeMake(scrollView.frame.size.
                                    width *[imageArray count],     scrollView.frame.size.height);
}

#pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)sender
{

    CGFloat pageWidth = self.scrollView.frame.size.width;
    //calculate current page in scrollview 
    int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    self.pageControl.currentPage = page;
    NSLog (@"page %d",page);

    if (page==0) {
        //change the image caption
        self.label.text = [NSString stringWithFormat:@"%s","Hello"];
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.0];
        [_label setAlpha:1];
        [UIView commitAnimations];
    }

    if (page==1) {
        //change the image caption
         self.label.text = [NSString stringWithFormat:@"%s","World"];
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.0];
        [_label setAlpha:1];
        [UIView commitAnimations];

    }

    if (page==2) {
        //change the image caption
        self.label.text = [NSString stringWithFormat:@"%s","Foobar"];
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.0];
        [_label setAlpha:1];
        [UIView commitAnimations];

      }

}

- (IBAction)done:(id)sender
{
    [self.delegate aboutViewControllerDidFinish:self];

}

@end

在(lldb)bt之后:

 * thread #1: tid = 0x1c8f63, 0x012d2b58 Foundation`_NSLockError, queue = 'com.apple.main-thread, stop reason = breakpoint 1.1
        frame #0: 0x012d2b58 Foundation`_NSLockError
        frame #1: 0x01247153 Foundation`-[NSRecursiveLock dealloc] + 159
        frame #2: 0x01820692 libobjc.A.dylib`objc_object::sidetable_release(bool) + 268
        frame #3: 0x01821adf libobjc.A.dylib`-[NSObject release] + 25
        frame #4: 0x05a89385 UIFoundation`_freeExtraData + 48
        frame #5: 0x05a895d5 UIFoundation`-[NSLayoutManager dealloc] + 381
        frame #6: 0x01820692 libobjc.A.dylib`objc_object::sidetable_release(bool) + 268
        frame #7: 0x01821adf libobjc.A.dylib`-[NSObject release] + 25
        frame #8: 0x00a91065 UIKit`-[UITextView dealloc] + 168
        frame #9: 0x00453e6b UIKit`-[UIView release] + 89
        frame #10: 0x0045f2d4 UIKit`-[UIView(Hierarchy) removeFromSuperview] + 292
        frame #11: 0x0047b4fd UIKit`-[UIScrollView removeFromSuperview] + 84
        frame #12: 0x004565db UIKit`-[UIView dealloc] + 432
        frame #13: 0x00477eaf UIKit`-[UIScrollView dealloc] + 1156
        frame #14: 0x00453e6b UIKit`-[UIView release] + 89
        frame #15: 0x0045f2d4 UIKit`-[UIView(Hierarchy) removeFromSuperview] + 292
        frame #16: 0x0047b4fd UIKit`-[UIScrollView removeFromSuperview] + 84
        frame #17: 0x004565db UIKit`-[UIView dealloc] + 432
        frame #18: 0x00453e6b UIKit`-[UIView release] + 89
        frame #19: 0x01ba2380 CoreFoundation`CFRelease + 272
        frame #20: 0x01bc18b4 CoreFoundation`-[__NSArrayM dealloc] + 196
        frame #21: 0x01820692 libobjc.A.dylib`objc_object::sidetable_release(bool) + 268
        frame #22: 0x0181fe81 libobjc.A.dylib`objc_release + 49
        frame #23: 0x01820ce7 libobjc.A.dylib`(anonymous      namespace)::AutoreleasePoolPage::pop(void*) + 537
        frame #24: 0x01bc1fc8 CoreFoundation`_CFAutoreleasePoolPop + 24
        frame #25: 0x00402c6e UIKit`_wrapRunLoopWithAutoreleasePoolHandler + 59
        frame #26: 0x01be89ee     CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
        frame #27: 0x01be893f CoreFoundation`__CFRunLoopDoObservers + 399
        frame #28: 0x01bc6cb0 CoreFoundation`__CFRunLoopRun + 1936
        frame #29: 0x01bc610d CoreFoundation`CFRunLoopRunSpecific + 445
        frame #30: 0x01bc5f3b CoreFoundation`CFRunLoopRunInMode + 123
        frame #31: 0x032e2ff2 GraphicsServices`GSEventRunModal + 192
        frame #32: 0x032e2e19 GraphicsServices`GSEventRun + 104
        frame #33: 0x004054eb UIKit`UIApplicationMain + 1225
        frame #34: 0x0000789d Monarch`main(argc=1, argv=0xbfffee1c) + 141 at main.m:16

我的問題是為什么首先要釋放NSRecursiveLock

我從沒在代碼的任何地方提到過NSRecursiveLock 關於此,在SO上也有類似的問題,但問題並不十分詳細。

ARC在這里起作用嗎?

我不知道它是否與您的問題有關,但我認為您的屬性配置不正確。 建議對“ IBOutlet”屬性使用“弱”而不是“強”或“分配”(通常,出口是視圖控制器的“ view”屬性的子視圖,因此這些子視圖由該“ view”屬性保留) 。

另外,您有一個使用強AND保留的委托,您不需要兩者,因為您正在使用ARC,因此只使用“ strong”關鍵字,就不再使用“ retain”。 順便說一句,由於它是委托,因此應使用“弱”屬性,以避免循環引用。

在NSRecursiveLock仍在使用時被釋放的情況下,問題出在IDE Xcode上。 使用最新的官方版本可以解決此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM