【问题标题】:NSMutableArray object values not being retained when returning from my model .m file从我的模型 .m 文件返回时未保留 NSMutableArray 对象值
【发布时间】:2012-03-13 04:39:21
【问题描述】:

新手错误?

我正在开发一个测验应用程序,该应用程序使用来自视图控制器的答案结果,为 KeepScore 模型 .m 文件中的 totalCorrect 和 totalTried 值创建 NSMutableArray 对象,并且模型将分数返回给我的视图控制器。然后视图控制器在我的视图中更新我的分数标签。然后我使用 UINavigationController 转到我的下一个视图控制器,然后等待用户输入下一个测验问题的答案。问题是下次我从视图控制器 2 调用我的 KeepScore 模型 .m 文件时,KeepScore 模型 .m 中的 NSMutableArray 对象已恢复为 Null 值。在从我的 KeepScore .m 模型返回到我的视图控制器 1 之前,我确保我的 NSMutableArray 对象值是正确的(非 Null)。我正在使用带有 ARC 的 Xcode 4.3.1 的 iOS 5.1。我在 .m 模型文件中的私有 API 声明中的 NSMutableArray 属性很强大。当我返回视图控制器时,KeepScore 模型 .m 不应该保留我的数组对象值,以便在我从下一个视图控制器调用模型时再次使用它们吗?我想先问一下措辞,看看是否有人能理解我的逻辑。如果有帮助,我会发布代码。

这是我的 KeepScore.h 模型 #导入

@interface KeepScore : NSObject

- (float)score:(BOOL)questionCorrect:(BOOL)questionTotal:(BOOL)firstScoringPass;
@end

这是我的 KeepScore.m 模型实现:

#import "KeepScore.h"

@interface KeepScore()
@property (nonatomic, strong) NSMutableArray *correctScoreValues;
@end

@implementation KeepScore

@synthesize correctScoreValues = _correctScoreValues;

- (NSMutableArray *)correctScoreValues
{
    if (_correctScoreValues == nil) _correctScoreValues = [[NSMutableArray alloc] init];
    return _correctScoreValues;
}

- (float)score:(BOOL)questionCorrect:(BOOL)questionTotal:(BOOL)firstScoringPass {

int totalTried;
int totalCorrect;
NSLog(@"firstScoringPass = %@", firstScoringPass ? @"YES" : @"NO");
NSLog(@"questionCorrect = %@", questionCorrect ? @"YES" : @"NO");
NSLog(@"questionTotal = %@", questionTotal ? @"YES" : @"NO");
if (firstScoringPass) {
    int totalTriedInt = 0;
    int totalCorrectInt = 0;
    NSNumber *correct = [NSNumber numberWithInt:totalCorrectInt];
    NSNumber *tried = [NSNumber numberWithInt:totalTriedInt];
    [self.correctScoreValues addObject:correct];
    [self.correctScoreValues addObject:tried];
    firstScoringPass = NO;
}

if (questionCorrect) {
    totalCorrect = ([[self.correctScoreValues objectAtIndex:0] intValue] + 1);
    NSLog(@"totalCorrect = %d", totalCorrect);
    NSNumber *correct = [NSNumber numberWithInt:totalCorrect];
    NSLog(@"correct = %@", correct);
    [self.correctScoreValues replaceObjectAtIndex:0 withObject:correct];
    NSLog(@"correct value in array = %d",[[self.correctScoreValues objectAtIndex:0] intValue]);
} else {
    totalCorrect = [[self.correctScoreValues objectAtIndex:0] intValue];
}

NSLog(@"totalCorrect = %d", totalCorrect);
if (questionTotal) {
    NSLog(@"tried value in array = %d", [[self.correctScoreValues objectAtIndex:1] intValue]);
    totalTried  = ([[self.correctScoreValues objectAtIndex:1] intValue] + 1);
    NSNumber *tried = [NSNumber numberWithInt:totalTried];
    [self.correctScoreValues replaceObjectAtIndex:1 withObject:tried];
    NSLog(@"tried value in array = %d", [[self.correctScoreValues objectAtIndex:1] intValue]);
}

float score = (totalCorrect/totalTried);
NSLog(@"score = %0.2f", score);
NSLog(@"totalCorrect = %d, totalTried = %d", totalCorrect, totalTried);

NSLog(@"correct value in array = %d", [[self.correctScoreValues objectAtIndex:0] intValue]);
NSLog(@"tried value in array = %d", [[self.correctScoreValues objectAtIndex:1] intValue]);

return score;
}
@end

这是我的 ViewControllers .m 文件之一:

#import "MapQuizViewController.h"
#import "KeepScore.h"

@interface MapQuizViewController()
@property (nonatomic, strong) KeepScore *scoreModel;
@property (nonatomic) BOOL questionTotal;
@property (nonatomic) BOOL questionCorrect;
@property (nonatomic) BOOL firstScoringPass;
@end

@implementation MapQuizViewController
@synthesize gradeLabel = _gradeLabel;
@synthesize scoreLabel = _scoreLabel;

@synthesize scoreModel = _scoreModel;
@synthesize questionTotal = _questionTotal;
@synthesize questionCorrect = _questionCorrect;
@synthesize firstScoringPass = _firstScoringPass;

- (KeepScore *)scoreModel;
{
    if (!_scoreModel) _scoreModel = [[KeepScore alloc] init];
    return _scoreModel;
}

- (IBAction)answerButtonPressed:(UIButton *)sender 
{

NSString *answerChoice = sender.currentTitle;
NSString *correct = [NSString stringWithFormat:@"Correct!"];
NSString *incorrect = [NSString stringWithFormat:@"Incorrect"];
self.questionTotal = YES;
self.firstScoringPass = YES;
if ([answerChoice isEqualToString:@"Australia"]) {
    self.gradeLabel.textColor = [UIColor blueColor];
    self.gradeLabel.text = [NSString stringWithFormat:@"%@",correct];
    self.questionCorrect = YES;
    self.scoreLabel.text = [NSString stringWithFormat:@"%0.2f",[self.scoreModel score:_questionCorrect :_questionTotal :_firstScoringPass]];
} else if ([answerChoice isEqualToString:@"U.S."]) {
    self.gradeLabel.textColor = [UIColor redColor];
    self.gradeLabel.text = [NSString stringWithFormat:@"%@", incorrect];
    self.questionCorrect = NO;        
    self.scoreLabel.text = [NSString stringWithFormat:@"%0.2f",[self.scoreModel score:_questionCorrect :_questionTotal :_firstScoringPass]];
} else if ([answerChoice isEqualToString:@"China"]) {
    self.gradeLabel.textColor = [UIColor redColor];
    self.gradeLabel.text = [NSString stringWithFormat:@"%@", incorrect];
    self.questionCorrect = NO;        
    self.scoreLabel.text = [NSString stringWithFormat:@"%0.2f",[self.scoreModel score:_questionCorrect :_questionTotal :_firstScoringPass]];
}
}
- (void)viewDidUnload {
  [self setScoreLabel:nil];
   [super viewDidUnload];
  }
@end

【问题讨论】:

  • 请提供一些代码。你是如何创建NSMutableArray 的?你是如何使用它的?
  • 我在 KeepScore.m 模型中创建了我的 NSMutableArray 作为私有属性。然后我用它来存储我的正确和全部对象。在我的 KeepScore.m 模型的第一遍结束时,我的数组对象都具有所需的值 1(以获得正确答案)。但是,当我继续执行代码时,我使用 UINavigationController 转到下一个视图(这是另一个视图控制器(不包括在内))。该视图控制器使用不同的按钮 NSString 值以相同的方式工作,并再次调用 KeepScore。但是,我在 KeepScore 数组中的对象值为 NULL。为什么不保存?
  • @moosgummi,我已经发布了代码。
  • 看起来是因为每个视图控制器都有一个KeepScore,当导航到下一个视图控制器时,将创建一个新的KeepScore 。尝试制作KeepScore 单例并查看
  • 我只有一个 KeepScore.m 文件,我认为两个视图控制器都通过 score 方法调用它。您是说在运行时会创建一个新的 KeepScore,即使它是一个 .m 文件?我需要学习 Singleton。

标签: ios nsmutablearray automatic-ref-counting


【解决方案1】:

首先,单个 .m 文件没有任何意义。我认为您假设每个 .m 文件都有一个 Class 实例,这是不正确的。

例如

// in .m file
static int *myInt; // only one `myInt` exist

// in .h or .m file
@interface MyClass : NSObject {
    int myVar;    // each MyClass instance will have its own `myVar` which are different
}

// somewhere else
MyClass *a = [[MyClass alloc] init];
MyClass *b = [[MyClass alloc] init];
a->myVar = 1;
b->myVar = 2;
// a->myVar is 1 and b->myVar is 2

如果您没有传递您的 KeepScore 实例,则新创建的实例将没有以前的数据。

您必须将 KeepScore 设为单例或将其从旧视图控制器传递到新视图控制器

【讨论】:

    猜你喜欢
    • 2012-01-13
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多