帮助理解Objective C中.h文件中声明的变量范围

时间:2011-02-28 20:17:04

标签: iphone objective-c

我对NSMutableArray和范围有疑问,我希望能够深入了解。我基本上想要为NSNumber对象创建一个全局可变数组。我试图用6个NSNumber对象初始化数组。这种方法有效,但当我在viewDidLoad中执行此操作然后尝试在名为generateScores的自定义方法(从IB中的按钮调用)中访问数组元素时,我得到例外。

当我在其中放入一些断点时,似乎数组中的对象在一个方法中设置得很好但在另一个方法中没有。所以我想我不理解数组的范围。请注意,当我在这些函数中使用单个NSNumber(变量名称强度)时,它设置正常,我可以从其他方法访问它。这就是为什么我认为这是我对NSMutableArray中对象的误解或者我是如何设置它们的。

我根据我玩的东西得到不同的例外情况,但主要的一个就是当我做

arrayCount = [scoresNSNumbers count];

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

所以在我看来,如果ScoreNSNumbers没有被初始化,它假定数组是String类型而不是NSNumbers还是什么?

对我来说,事情变得很糟糕的是,如果我把两行代码设置为我的generateScores方法中的ScoreNSNumbers数组,它运行正常但是当我离开该方法时,数组中没有对象就像现在它在viewDidLoad中一样。

非常感谢任何智慧!

.h文件:

#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文件:

#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

2 个答案:

答案 0 :(得分:2)

在'viewDidLoad'方法上:

scoresNSNumbers = ...

self.scoresNSNumbers = ...

会不一样......

使用第一个选项,您可以直接分配实例变量。 使用第二个方法,您将通过setter方法,它将自动保留对象,因为您以这种方式定义了属性。

答案 1 :(得分:0)

你的问题不是范围,它的工作正常,但是数组被自动释放,当你尝试访问它时,你访问一些随机的其他对象,它驻留在旧对象的内存区域。在你的情况下,它是一个NSString。

你能做什么:

  1. 保留对象
  2. 使用[[NSMutableArray alloc] init]而不是返回自动释放变量的东西
  3. 哦,阅读内存指南,深入了解ObjC如何处理内存(或更好地说NSObject / Cocoa如何)。