NSRecursiveLock Deallocated

扶醉桌前 提交于 2020-01-07 05:19:07

问题


I Have an iOS app with multiple view controllers and ARC enabled. One of the view controllers has an IBOutlet for UIScrollView and UIPageControl. When that view controller is loaded this error is printed in the console:

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

While trying to fix the problem, I created a symbolic breakpoint for the symbol _NSLockError with the module set to Foundation. Now Xcode breaks with breakpoint 1.1 on "0x12d2b58: pushl %ebp", which is on thread 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  

Here is the code in my application for the problematic ViewController:

header file (.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

implementation file (.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

After a (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

My question is why was NSRecursiveLock deallocated in the first place?

I never mentioned NSRecursiveLock any where in the code. There was a similar question on SO about this but it was not very detailed.

Does ARC come into play here?


回答1:


I don't know if it is related to your problem, but i think your properties are not correctly configured. It is recommended to use "weak" and not "strong" or "assign" for "IBOutlet" properties (usually the outlet is a subview of the view controller's "view" property, so these subviews are retained by this "view" property).

Also you have a delegate using strong AND retain, you don't need both, since you're using ARC, use the "strong" keyword only, and don't use the "retain" anymore. And by the way, since it is a delegate, you should use a "weak" property in order to avoid circular reference.




回答2:


In this case of NSRecursiveLock being Deallocated while still in use, the problem was with the IDE, Xcode. Using the latest official version of it resolved the issue.



来源:https://stackoverflow.com/questions/18142002/nsrecursivelock-deallocated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!