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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 21:17:09  来源:igfitidea点击:

NSRangeException

iphoneobjective-cxcodensarray

提问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 IBOutletproperties. 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;