开发者

Help understanding scope of variables declared in a .h file in Objective C

开发者 https://www.devze.com 2023-02-14 03:47 出处:网络
I have an issue with NSMutableArray and scope I am hoping to get some insight into.I basically want to have a global mutable array for NSNumber ojects.I am trying to initialize the array with 6 NSNumb

I have an issue with NSMutableArray and scope I am hoping to get some insight into. I basically want to have a global mutable array for NSNumber ojects. I am trying to initialize the array with 6 NSNumber objects. This sort of works but when I do this in say viewD开发者_如何学CidLoad and then try and access array elements in a custom method called generateScores (called from a button in IB) I get exceptions.

When I put some breakpoints in it seems like the objects in the array are set fine in one method but aren't there in the other. So I am thinking I don't understand scope of arrays properly. Note that when I just use a single NSNumber (variable name strength) inside these functions it sets fine and I can access it from other methods. That is why I think it is my misunderstanding of the objects in the NSMutableArray or how I am setting them.

I get different exceptions based on things I was playing with but one main one is when I do

arrayCount = [scoresNSNumbers count];

is

2011-02-28 15:30:51.347 NSArray Test[6145:207] -[NSCFString count]: unrecognized selector sent to instance 0x6031e20

So it looks to me like if scoresNSNumbers isn't initialized that it assumes the array is of String type instead of NSNumbers or something?

Where things get wonky for me is that if I put the two lines of code to set an array to scoresNSNumbers inside of my generateScores method it runs fine but the array doesn't have the objects in it when I leave that method, just like now when it is in viewDidLoad.

Any wisdom is greatly appreciated!

.h file:

#import <UIKit/UIKit.h>

@interface NSArray_TestViewController : UIViewController {

    NSNumber *strength;
    NSMutableArray *scoresNSNumbers;
}

@property (nonatomic, retain) NSNumber *strength;
@property (nonatomic, retain) NSMutableArray *scoresNSNumbers;

- (IBAction)generateScores:(id)sender;

@end

.m file:

#import "NSArray_TestViewController.h"

@implementation NSArray_TestViewController

@synthesize strength, scoresNSNumbers;

- (IBAction)generateScores:(id)sender {
    int diceRoll = 0, arrayCount = 0;
    NSNumber *aScore;

    arrayCount = [scoresNSNumbers count];

for (int i = 0; i < arrayCount; i++) {
        diceRoll = (int)((arc4random() % 12) + 1);
        strength = [NSNumber numberWithInt:diceRoll];
        aScore = [NSNumber numberWithInt:diceRoll];

        [scoresNSNumbers replaceObjectAtIndex:i withObject:aScore];
        NSLog(@"%@\n", [scoresNSNumbers objectAtIndex:i]);
    }
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    scoresNSNumbers = [NSMutableArray arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:0], [NSNumber numberWithInt:0],
        NSNumber numberWithInt:0], [NSNumber numberWithInt:0], [NSNumber numberWithInt:0], nil];
    [super viewDidLoad];
}

- (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;
    strength = nil;
    scoresNSNumbers = nil;
}

- (void)dealloc {
    [strength release];
    [scoresNSNumbers release];

    [super dealloc];
}

@end


On the 'viewDidLoad' method:

scoresNSNumbers = ...

or

self.scoresNSNumbers = ...

won't be the same...

With the first option, you assign directly the instance variable. With the second one, you'll pass through the setter method, that will retain the object automatically, because you defined the property that way.


Your problem isn't the scope, its works just fine, but the array gets autoreleased and when you try to access it, you access some random other object that resides in the memory area of the old object. In your case it is an NSString.

What you can do:

  1. retain the object
  2. Use [[NSMutableArray alloc] init] instead of something that returns an autorelease variable

Oh and read the memory guidelines to get more insight into the whole process how ObjC handles memory (or better saying how NSObject/Cocoa does).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号