xcode 异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6378311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NSRangeException
提问by Paul Woidke
I'm trying to use two buttons to cycle through an array of images. I'm using a buttonPressed function that identifies the tag of the left or right button, and should change the image that is displayed. Problem is, the function works perfectly when going right (incrementing the array), but if I try to go left (decrement) the program crashes. I've tried changing the values the variables are initialized to and the values used to cycle the arrays, but nothing seems to fix it. Any help is greatly appreciated.
我正在尝试使用两个按钮来循环浏览一组图像。我正在使用 buttonPressed 函数来标识左按钮或右按钮的标签,并且应该更改显示的图像。问题是,该函数在向右(增加数组)时运行良好,但如果我尝试向左(减少)程序崩溃。我尝试更改变量初始化的值以及用于循环数组的值,但似乎没有任何解决方法。任何帮助是极大的赞赏。
.h
。H
// FirstViewController.h
// TabTemplate
//
// Created by Paul R Woidke on 6/1/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#include <stdlib.h>
@interface FirstViewController : UIViewController {
UIImageView* hat;
UIImageView* shirt;
UIImageView* pants;
UIImageView* shoes;
NSArray *hatArray;
NSArray *shirtArray;
NSArray *pantsArray;
NSArray *shoesArray;
}
@property (nonatomic, retain) IBOutlet UIImageView* hat;
@property (nonatomic, retain) IBOutlet UIImageView* shirt;
@property (nonatomic, retain) IBOutlet UIImageView* pants;
@property (nonatomic, retain) IBOutlet UIImageView* shoes;
@property (nonatomic, retain) IBOutlet NSArray* hatArray;
@property (nonatomic, retain) IBOutlet NSArray* shirtArray;
@property (nonatomic, retain) IBOutlet NSArray* pantsArray;
@property (nonatomic, retain) IBOutlet NSArray* shoesArray;
- (IBAction)buttonPressed:(id) sender;
- (IBAction)lockButtonPressed:(id) sender;
- (IBAction)weatherButtonPressed:(id) sender;
- (IBAction)randomizeButtonPressed:(id) sender;
@end
.m
.m
// FirstViewController.m
// TabTemplate
//
// Created by Paul R Woidke on 6/1/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "FirstViewController.h"
@implementation FirstViewController
@synthesize hat;
@synthesize shirt;
@synthesize pants;
@synthesize shoes;
@synthesize hatArray;
@synthesize shirtArray;
@synthesize pantsArray;
@synthesize shoesArray;
NSInteger hatImage;
NSInteger shirtImage;
NSInteger pantsImage;
NSInteger shoesImage;
-(void) displayOutfit {
UIImage *hatImg = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg];
UIImage *shirtImg = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg];
UIImage *pantsImg = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg];
UIImage *shoesImg = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg];
}
- (IBAction)buttonPressed:(id) sender {
NSInteger senderLabel = [sender tag];
switch (senderLabel) {
//Going right
case 2:
NSLog(@"Hat number: %d", hatImage);
NSLog(@"Hat Array count: %d", [hatArray count]);
if (hatImage == [hatArray count])
hatImage = 0;
UIImage *hatImg2 = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg2];
hatImage++;
break;
case 4:
if (shirtImage == [shirtArray count])
shirtImage = 0;
UIImage *shirtImg2 = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg2];
shirtImage++;
break;
case 6:
if (pantsImage == [pantsArray count])
pantsImage = 0;
UIImage *pantsImg = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg];
pantsImage++;
break;
case 8:
if (shoesImage == [shoesArray count])
shoesImage = 0;
UIImage *shoesImg2 = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg2];
shoesImage++;
break;
//Going left
case 1:
if (hatImage == 0)
hatImage = 3;
UIImage *hatImg = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg];
hatImage--;
break;
case 3:
if ((shirtImage) == 0)
shirtImage = [shirtArray count];
UIImage *shirtImg = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg];
shirtImage--;
break;
case 5:
if ((pantsImage) == 0)
pantsImage = [pantsArray count];
UIImage *pantsImg2 = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg2];
pantsImage--;
break;
case 7:
if ((shoesImage) == 0)
shoesImage = [shoesArray count];
UIImage *shoesImg = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg];
shoesImage--;
break;
}
}
- (IBAction)lockButtonPressed:(id) sender {
NSLog(@"Lock Button Pressed");
}
- (IBAction)weatherButtonPressed:(id) sender {
NSLog(@"Weather Button Pressed");
}
- (IBAction)randomizeButtonPressed:(id) sender {
NSLog(@"Randomize Button Pressed");
int randHat = rand() % [hatArray count];
int randShirt = rand() % [shirtArray count];
int randPants = rand() % [pantsArray count];
int randShoes = rand() % [shoesArray count];
NSLog(@"hat %d\nshirt %d\npants %d\nshoes %d", randHat, randShirt, randPants, randShoes);
hatImage = randHat;
shirtImage = randShirt;
pantsImage = randPants;
shoesImage = randShoes;
[self displayOutfit];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
//Generate image arrays
hatArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"h1.png"],
[UIImage imageNamed:@"h2.png"],
[UIImage imageNamed:@"h3.png"],
nil] retain];
shirtArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"s1.png"],
[UIImage imageNamed:@"s2.png"],
[UIImage imageNamed:@"s3.png"],
[UIImage imageNamed:@"s4.png"],
[UIImage imageNamed:@"s5.png"],
[UIImage imageNamed:@"s6.png"],
nil] retain];
pantsArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"p1.png"],
[UIImage imageNamed:@"p2.png"],
[UIImage imageNamed:@"p3.png"],
[UIImage imageNamed:@"p4.png"],
nil] retain];
shoesArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"ss1.png"],
[UIImage imageNamed:@"ss2.png"],
[UIImage imageNamed:@"ss3.png"],
nil] retain];
hatImage = 0;
shirtImage = 0;
pantsImage = 0;
shoesImage = 0;
UIImage *hatImg = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg];
UIImage *shirtImg = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg];
UIImage *pantsImg = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg];
UIImage *shoesImg = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg];
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.hat = nil;
self.shirt = nil;
self.pants = nil;
self.shoes = nil;
self.hatArray = nil;
self.shirtArray = nil;
self.pantsArray = nil;
self.shoesArray = nil;
}
- (void)dealloc {
[hat release];
[shirt release];
[pants release];
[shoes release];
[hatArray release];
[shirtArray release];
[pantsArray release];
[shoesArray release];
[super dealloc];
}
@end
Console output (displays array count and value of current image):
控制台输出(显示当前图像的数组计数和值):
[Session started at 2011-06-16 16:30:50 -0400.]
2011-06-16 16:31:03.192 TabTemplate[2478:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** Call stack at first throw:
(
0 CoreFoundation 0x00db3be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f085c2 objc_exception_throw + 47
2 CoreFoundation 0x00da980c -[__NSArrayI objectAtIndex:] + 236
3 TabTemplate 0x000026c8 -[FirstViewController buttonPressed:] + 569
4 UIKit 0x002bca6e -[UIApplication sendAction:to:from:forEvent:] + 119
5 UIKit 0x0034b1b5 -[UIControl sendAction:to:forEvent:] + 67
6 UIKit 0x0034d647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
7 UIKit 0x0034c1f4 -[UIControl touchesEnded:withEvent:] + 458
8 UIKit 0x002e10d1 -[UIWindow _sendTouchesForEvent:] + 567
9 UIKit 0x002c237a -[UIApplication sendEvent:] + 447
10 UIKit 0x002c7732 _UIApplicationHandleEvent + 7576
11 GraphicsServices 0x016e9a36 PurpleEventCallback + 1550
12 CoreFoundation 0x00d95064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
13 CoreFoundation 0x00cf56f7 __CFRunLoopDoSource1 + 215
14 CoreFoundation 0x00cf2983 __CFRunLoopRun + 979
15 CoreFoundation 0x00cf2240 CFRunLoopRunSpecific + 208
16 CoreFoundation 0x00cf2161 CFRunLoopRunInMode + 97
17 GraphicsServices 0x016e8268 GSEventRunModal + 217
18 GraphicsServices 0x016e832d GSEventRun + 115
19 UIKit 0x002cb42e UIApplicationMain + 1160
20 TabTemplate 0x00002012 main + 84
21 TabTemplate 0x00001f92 start + 54
)
terminate called after throwing an instance of 'NSException'
[Session started at 2011-06-16 16:31:13 -0400.]
2011-06-16 16:31:15.966 TabTemplate[2481:207] Hat number: 0
2011-06-16 16:31:15.968 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:16.390 TabTemplate[2481:207] Hat number: 1
2011-06-16 16:31:16.391 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:16.790 TabTemplate[2481:207] Hat number: 2
2011-06-16 16:31:16.791 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:17.446 TabTemplate[2481:207] Hat number: 3
2011-06-16 16:31:17.447 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:17.902 TabTemplate[2481:207] Hat number: 1
2011-06-16 16:31:17.903 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:18.199 TabTemplate[2481:207] Hat number: 2
2011-06-16 16:31:18.199 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:18.526 TabTemplate[2481:207] Hat number: 3
2011-06-16 16:31:18.527 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:20.503 TabTemplate[2481:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** Call stack at first throw:
(
0 CoreFoundation 0x00db3be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f085c2 objc_exception_throw + 47
2 CoreFoundation 0x00da980c -[__NSArrayI objectAtIndex:] + 236
3 TabTemplate 0x000026c8 -[FirstViewController buttonPressed:] + 569
4 UIKit 0x002bca6e -[UIApplication sendAction:to:from:forEvent:] + 119
5 UIKit 0x0034b1b5 -[UIControl sendAction:to:forEvent:] + 67
6 UIKit 0x0034d647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
7 UIKit 0x0034c1f4 -[UIControl touchesEnded:withEvent:] + 458
8 UIKit 0x002e10d1 -[UIWindow _sendTouchesForEvent:] + 567
9 UIKit 0x002c237a -[UIApplication sendEvent:] + 447
10 UIKit 0x002c7732 _UIApplicationHandleEvent + 7576
11 GraphicsServices 0x016e9a36 PurpleEventCallback + 1550
12 CoreFoundation 0x00d95064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
13 CoreFoundation 0x00cf56f7 __CFRunLoopDoSource1 + 215
14 CoreFoundation 0x00cf2983 __CFRunLoopRun + 979
15 CoreFoundation 0x00cf2240 CFRunLoopRunSpecific + 208
16 CoreFoundation 0x00cf2161 CFRunLoopRunInMode + 97
17 GraphicsServices 0x016e8268 GSEventRunModal + 217
18 GraphicsServices 0x016e832d GSEventRun + 115
19 UIKit 0x002cb42e UIApplicationMain + 1160
20 TabTemplate 0x00002012 main + 84
21 TabTemplate 0x00001f92 start + 54
)
terminate called after throwing an instance of 'NSException'
回答by Simon Whitaker
In your "going left" cases you're setting the array index out of bounds. For example:
在“向左”的情况下,您将数组索引设置为越界。例如:
if ((shirtImage) == 0)
shirtImage = [shirtArray count];
The last item in an array has the index [arrayObj count] - 1
.
数组中的最后一项具有索引[arrayObj count] - 1
。
In fact, you're setting the value of shirtImage anywhere in the range 1..arrayLength, where it should be in the range 0..arrayLength-1. I'd suggest you increment/decrement your index first, then check its bounds, then index into the array. For example:
实际上,您正在 1..arrayLength 范围内的任何位置设置shirtImage 的值,该值应在 0..arrayLength-1 范围内。我建议你先增加/减少索引,然后检查它的边界,然后索引到数组中。例如:
case 2:
// increment the index
hatImage++;
// wrap around if you've gone beyond the bounds of the array
if (hatImage == [hatArray count])
hatImage = 0;
// Index into the array
[hat setImage:[hatArray objectAtIndex:hatImage]];
回答by Abizern
NSRangeException - that means you've overrun the bounds of an array.
NSRangeException - 这意味着您已经超出了数组的边界。
An aside: You're declaring these as IBOutlet
properties. What are you hooking them up to?
旁白:您将这些声明为IBOutlet
属性。你在勾搭他们干什么?
@property (nonatomic, retain) IBOutlet NSArray* hatArray;
@property (nonatomic, retain) IBOutlet NSArray* shirtArray;
@property (nonatomic, retain) IBOutlet NSArray* pantsArray;
@property (nonatomic, retain) IBOutlet NSArray* shoesArray;