我有一个带有多个视图控制器并启用了 ARC 的 iOS 应用程序。其中一个视图控制器有一个IBOutlet
forUIScrollView
和UIPageControl
. 加载该视图控制器时,控制台中会打印此错误:
*** -[NSRecursiveLock dealloc]: lock (<NSRecursiveLock: 0xcb88cb0> '(null)')
deallocated while still in use
在尝试解决问题时,我为符号设置了一个符号断点,_NSLockError
并将模块设置为 Foundation。"0x12d2b58: pushl %ebp"
现在 Xcode在线程 1上以断点 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
任何地方。关于这个有一个类似的问题,但不是很详细。
ARC在这里发挥作用吗?