【问题标题】:Where to Initialize NSMutableArray to Prevent Erasure在哪里初始化 NSMutableArray 以防止擦除
【发布时间】:2014-07-25 06:35:08
【问题描述】:

我正在尝试创建一个 NSMutableArray,它在按下按钮时添加了一个浮点数(转换为 NSInteger)。该按钮连接到一个timerViewController,其实现文件中的代码块如下(本题的if语句可以忽略):

- (IBAction)timeSaveButton:(UIButton *)sender {
    if ([self.timerStartOrStop.titleLabel.text  isEqual: @"Start"]){
        RecordedTimes *myTimes = [[RecordedTimes alloc] init];
        [myTimes addANewTime: self.timerTime];
    }
}

它引用的“RecordedTimes”类在 .h 文件中声明了 NSMutableArray 和“addANewTime”方法

@interface RecordedTimes : NSObject

@property (nonatomic) NSMutableArray *recordedTimes;

-(void)addANewTime: (float) timerTime;

@end

它的实现文件是

@implementation RecordedTimes

-(void) addANewTime:(float)timerTime{
    NSMutableArray *myTimes = [[NSMutableArray alloc] init];
    [myTimes addObject:[NSString stringWithFormat:@"%f", timerTime]];
}

@end

问题是每次我保存一个新时间时,数组都会清空并只存储最近的 timerTime。我知道这是因为我的 viewController(和 addANewTime 方法)每次都会初始化数组,导致它擦除其内容。如何解决这个问题以及在哪里初始化数组是我很困惑的地方。

请在您的回复中详细说明。我是 XCode 和 Objective-C 的新手。谢谢。

【问题讨论】:

  • 这是关于实例变量的范围。 techotopia.com/index.php/…
  • 尝试在 viewDidLoad 中初始化 NSMutableArray 以避免每次向 addANewTime 传递消息时都会重新初始化它。
  • 如果您找到任何符合您的问题的答案,请投票正确。

标签: ios objective-c initialization nsmutablearray


【解决方案1】:

您已经声明了名为 recordedTimesNSMutableArray 属性,但从未将其初始化为空数组。在方便的地方,比如init 方法,你可以初始化它:

- (id)init {
    self = [super init];
    if (self) {
        self.recordedTimes = [[NSMutableArray alloc] init];
    }
    return self;
}

然后把addANewTime:改成这样:

- (void)addANewTime:(float)timerTime{
    [self.recordedTimes addObject:[NSString stringWithFormat:@"%f", timerTime]];
}

这可确保您的可变数组属性被初始化一次(因为在您初始化对象时会调用一次 init),然后每次调用 addANewTime: 时都将其追加到数组的末尾。


此外,每次调用 timeSaveButton: 方法时,您都会重新创建 RecordedTimes 对象。您需要遵循相同的模式,并将其作为属性存储在视图控制器的类中,然后在 viewDidLoad 方法之类的某个地方设置一次。


旁白:您可能已经注意到,您不能在NSMutableArray 对象中存储int(或者,通常是原始,非对象类型)。您可以考虑使用[NSNumber numberWithInt:timerTime]timerTime 转换为NSNumber,并将其存储在数组中而不是字符串中。

【讨论】:

  • init 方法会进入哪个文件?而且,由于它的返回类型是 id,它不需要你在最后返回一些东西吗?
  • 您将 init 方法放在 RecordedTimes 类中。是的,不错的收获!我已经编辑了示例以返回自我。
  • 嗯,到目前为止,我还没有阅读有关 init 方法的任何内容。那么它基本上只是在初始化某个类的对象时才运行吗?
  • 进一步澄清。当您说“遵循相同的模式,并将其作为属性存储在视图控制器的类中”时,我假设您的意思是将 RecordedTimes 类声明为属性。会不会这样做:@property (nonatomic) RecordedTimes *myTimes;
  • 是的!记住只在 viewDidLoad 之类的地方初始化一次。
【解决方案2】:

要初始化一个属性,我通常会这样做:

在视图控制器的viewDidLoad 方法中。

(void)viewDidLoad {
    [super viewDidLoad];
    self.recordedTimes = [[NSMutableArray alloc] init];
}

或者在你需要的时候惰性初始化它,在这种情况下,当你第一次添加它时:

-(void) addANewTime:(float)timerTime {
    if (!self.recordedTimes) {
       self.recordedTimes = [[NSMutableArray alloc] init];
    }
    [self.recordedTimes addObject:[NSString stringWithFormat:@"%f", timerTime]];
}

另外,你做错了几件事:

  • 首先,您有一个局部变量,它在方法addANewTime 执行后被释放。相反,您应该声明一个@property,以便只要 viewController(或具有该属性的对象)还活着,您的数组就会保持活动状态。
  • 我假设您想使用 @property (nonatomic) NSMutableArray *recordedTimes; 执行此操作,但您实际上应该使用它,而不是使用局部变量。

【讨论】:

  • assignstrong 不相关。一个属性可以同时具有assignstrong 语义。此外,ARC 下的所有对象属性默认为strong
  • 我不知道!编辑了答案。 PS:该死,我已经无缘无故地写了strong一百万次......
  • 是的!当我发现我在浏览所有代码并删除 strong 时很开心:)
  • 我不能在我的 viewController 中使用 self.recordedTimes 因为它的recordedTimes 只在RecordedTimes 对象中声明。
【解决方案3】:
if ()
{
    RecordedTimes *myTimes = [[RecordedTimes alloc] init];
}

myTimes 实例仅在if {} 语句中有效。

-(void) addANewTime:(float)timerTime
{
    NSMutableArray *myTimes = [[NSMutableArray alloc] init];
}

另外,myTimes 实例仅在addNewTime: 方法中有效。

这就是为什么它似乎每次都初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-27
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多