简体   繁体   中英

Works on iOS Simulator but not on iPhone

The line of code works fine on the iOS Simulator 6.0, but is crashing when I try to run it on my iPhone, also running iOS6.

[menuView addSubview:mvc.view];

Why is this happening, and how can I fix it?

This is the more complete version of the code:

SDMenuViewController *mvc = [[SDMenuViewController alloc] init];
[menuView addSubview:mvc.view];

And this is what it is crashing with:

2012-10-08 21:32:32.423 CrunchCalculator1-2[21019:907] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </var/mobile/Applications/EDD23933-CE20-4AFD-A2B1-CDD56AD658E8/CrunchCalculator1-2.app> (loaded)' with name 'SDNestedTableView''
*** First throw call stack:
(0x39cd03e7 0x35ece963 0x39cd0307 0x39ee0fd1 0x39ee05ff 0x39dd9031 0x39e0786d 0x39d63419 0xb20d9 0x39d63541 0x39da3d29 0x39d9fac5 0x39de1199 0xb17c5 0x39da4a71 0x39da45f5 0x39d9c803 0x39d44ce7 0x39d44775 0x39d441b7 0x31e145f7 0x31e14227 0x39ca53e7 0x39ca538b 0x39ca420f 0x39c1723d 0x39c170c9 0x39d9b43d 0x39d98289 0xb1523 0x3792fb20)
libc++abi.dylib: terminate called throwing an exception

Thanks!

I'm not quite sure how it worked on your simulator (when I tried it on mine, I got the crash you list in your original question). Anyway, you can fix it by looking at the following items:

  • The main problem is that the NIB was not included in the bundle. Add it to the project target's "Copy Bundle Resources", eg:

复制捆绑包资源

  • While you're looking at your "Copy Bundle Resources", you'll also want to include SDSubCell.xib , SDGroupCell.xib , and add all of those PNG files, too.

  • As an aside, while it doesn't apparently cause the crash, the "File Owner" base class in SDNestedTableView NIB refers to a class that doesn't exist anywhere in this project. That can't be good. Anyway, you probably want to change that to SDMenuViewController or SDNestedTableViewController ;

设置文件的所有者基本类


It's a little unrelated to your crash, but as I look at the project, I see a worrying construct:

SDMenuViewController *mvc = [[SDMenuViewController alloc] initWithNibName:@"SDNestedTableView" bundle:nil];
[menuView addSubview:mvc.view];

You're creating a controller, grabbing its view, and either letting the view controller fall out of scope and be released (if you were using ARC) or leaking it (if not ARC).

I wasn't entirely sure from the original question whether you were doing addSubview as a way of transitioning to a new view (which is really bad practice) or whether you were doing view controller containment. As I look at the code, it appears you're doing the latter, though you're missing a few calls in your code. You might want to read up on view controller containment . And also check out that WWDC 2011 session 102 .

Anyway, those two lines of code above with the view controller alloc / init and the subsequent addSubview will leak in your non-ARC project (and would crash it if you ever went to ARC) and your view hierarchy is out of sync with your view controller hierarchy. I'd suggest you might want:

SDMenuViewController *mvc = [[[SDMenuViewController alloc] initWithNibName:@"SDNestedTableView" bundle:nil] autorelease];
[self addChildViewController:mvc];
[mvc didMoveToParentViewController:self];
[menuView addSubview:mvc.view];

Note the autorelease on that first line.

View controller containment can be powerful, but you want to make sure you do some of this basic housekeeping.


One final update:

I notice that there are some bugs that are in this code. First, your use of currentSection in item:setSubItem:forRowAtIndexPath won't work. You're setting that based upon the last expandingItem . So, if you click on one of the main items before expanding either one, the program will crash. Probably best is to eliminate the currentSection variable altogether and in item:setSubItem:forRowAtIndexPath , use item.cellIndexPath.row rather than your variable currentSection .

Unfortunately, this fix leads to a more serious problem, there appears to be an iOS 6 bug in the SDNestedTable class, itself. If you run this on iOS 6 and you expand your all of your items, scroll to the bottom and then scroll back to the top, the program will crash because the cellIndexPath property of the SDGroupItem *item returned by item:setSubItem:forRowAtIndexPath can be deallocated! If you turn on zombies in iOS 6, you'll see cellIndexPath has been released. I went and downloaded the original version and see the same problem there. The problem appears to be that cellIndexPath in SDGroupCell is defined as an assign property (which means that if iOS determines it no longer needed the indexPath it created for its own purposes, it will be released even though SDGroupCell maintains an assign reference to this released object). Just change the cellIndexPath property of SDGroupCell from assign to retain , and this iOS 6 bug goes away. I've informed the developer of SDNestedTable of this issue, but this change to retain will fix the problem of the code crashing in iOS 6.

[Edit: The author of SDNestedTable agreed with my assessment of the issue, and he reports that this issue has been fixed the latest version. - Rob]

Best wishes.

You should probably use initWithNibName: insead of just init in the first line. Not sure regarding your specific issue, but certainly something to try.

It looks like you're trying to instantiate a nib called SDNestedTableView.nib and it isn't present. Is the nib included as a project member?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM