【问题标题】:addObjects adds only last object to NSMutableArrayaddObjects 仅将最后一个对象添加到 NSMutableArray
【发布时间】:2016-02-19 19:29:31
【问题描述】:

我正在创建一个 Schedule 类并尝试在 ViewController 中循环输出所有事件。我创建了一个 Event 类和 Schedule 类。我正在循环遍历 NSMutableArray 以获取所有事件的文本。我的问题是,当我在 Schedule.m 文件中的 addNewEvent 方法中时,我用通过 addObject 添加的最后一个对象覆盖了我的 NSMutable 数组。我的目标是将所有事件对象一一添加到数组中并显示它们的文本。如果我可以为事件对象设置单独的 ID,那就太好了。我知道当我将对象添加到可变数组时,我可能需要遍历 addNewEvent 方法中的某些内容,但我不知道通过什么。我还认为也许我在错误的位置初始化了 NSMutableArray(它是 Schedule 类的属性),但是如果我将初始化程序移动到其他任何地方,它就会出错。

你能帮我解决这个问题吗?任何帮助将不胜感激!

我的代码如下。我有两个类(Event & Schedule)和一个 ViewController 文件。

事件.h:

@interface Event : NSObject

@property int eventId;

@property NSString * eventTitle;

@property NSString * eventDescription;

@property NSDate * eventDate;

-(void) logEvent;

-(NSString*) getEventText;

@end

事件.m:

#import "Event.h"

@implementation Event

-(NSString*) getEventText {

    NSString * eventText1 = [NSString stringWithFormat: @"\n\nEvent ID: %d.\n", _eventId];

    NSString * eventText2 = [eventText1 stringByAppendingFormat: @"Title: %@.\n", _eventTitle];

    NSString * eventText3 = [eventText2 stringByAppendingFormat:@"Description: %@.\n", _eventDescription];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.dateStyle = NSDateFormatterFullStyle;
    dateFormatter.timeStyle = NSDateFormatterShortStyle;

    NSString * eventText = [eventText3 stringByAppendingFormat:@"Date: %@.\n\n", [dateFormatter stringFromDate:_eventDate]];

    return eventText;
}

@end

Schedule.h:

@interface Schedule : NSObject

@property int idIndex;

@property NSMutableArray * scheduledEvents;

-(NSString*) getAllEventText;

-(void)addNewEventWithTitle:(NSString *)Title Description:(NSString *)Description andDate:(NSDate *)Date;

@end

Schedule.m:

#import "Schedule.h"
#import "Event.h"

@implementation Schedule

-(void)addNewEventWithTitle:(NSString *)Title Description:(NSString *)Description andDate:(NSDate *)Date {

    Event * event = [[Event alloc] init];

    _idIndex = 1;

    [event setEventTitle:Title];
    [event setEventDescription:Description];
    [event setEventDate:Date];
    [event setEventId:_idIndex];

    NSLog(@"%@", [event getEventText]);

    _scheduledEvents = [[NSMutableArray alloc] init];

    [_scheduledEvents addObject: event];

    NSLog(@"%lu", [_scheduledEvents count]);

}

-(NSString*) getAllEventText {

    NSString * allEventText;

    // loop through NSMutableArray calling each Event's getEventText method using a for loop

    for (int i=0; i<[_scheduledEvents count]; i++) {

        allEventText = [NSString stringWithFormat:@"Event %d: %@\n", i+1, [_scheduledEvents[i] getEventText] ];

        NSLog(@"%@", [_scheduledEvents[i] getEventText]);

    }

    // return concatenated string

    return allEventText;

}

@end

ViewController.m:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    Schedule * mySchedule = [[Schedule alloc] init];

    [mySchedule addNewEventWithTitle:@"My Birthday" Description:@"My most cherished birthday" andDate:[NSDate dateWithTimeIntervalSinceReferenceDate:484830000]];

    [mySchedule addNewEventWithTitle:@"Meeting with the Client" Description:@"My most important meeting" andDate:[NSDate dateWithTimeIntervalSinceReferenceDate:481302000]];

    [mySchedule addNewEventWithTitle:@"Appointment with Family Doctor" Description:@"My most urgent appointment" andDate:[NSDate dateWithTimeIntervalSinceReferenceDate:480270000]];

    [_outputTextView setText:[mySchedule getAllEventText]];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

【问题讨论】:

    标签: ios objective-c arrays nsmutablearray


    【解决方案1】:

    每次调用 addNewEventWithTitle:Description:andDate 时,您都会重新初始化 scheduleEvents。

    您必须在 viewDidLoad 方法中移动 _scheduledEvents = [[NSMutableArray alloc] init];

    【讨论】:

    • 它不允许我这样做。当我这样做时,Xcode 说:“使用未声明的标识符 '_scheduledEvents'。”
    • 好的,然后将该代码移动到 Schedule.m 文件中的 init 方法
    • 你的意思是做这样的事情: - (instancetype)init { self = [super init]; if (self) { _scheduledEvents = [[NSMutableArray alloc] init]; } 返回自我; }?当我这样做时,它仍然只将最后一个对象输出到我的 ViewController 视图。
    • 是的,没错。现在确保您删除了 _scheduledEvents = [[NSMutableArray alloc] init];里面 addNewEventWithTitle:Description:andDate
    【解决方案2】:

    问题出在这一行:

    -(void)addNewEventWithTitle:(NSString *)Title Description:(NSString *)Description andDate:(NSDate *)Date {
        // ...
        _scheduledEvents = [[NSMutableArray alloc] init]; // <--
        // ...
    }
    

    根据定义,如果_scheduledEvents 已经有任何值(现有数组),则该行会破坏该值并将其替换为新的空数组。因此,运行 addNewEvent... 方法的结果将始终_scheduledEvents 最终只包含这一事件。

    【讨论】:

    • 是的,我知道我将数组的初始化程序放在哪里有问题。如果我删除您指向的行,则不会将任何内容输出到我的 ViewController 视图。使用现在所在的行,输出最后添加的对象。
    • 我刚刚解释过了。毕竟,如果你没有在 some 点将一个空的 NSMutableArray 放入_scheduledEvents,那么就不会有一个,因此没有什么可以添加的,也没有任何反应。但是每次调用这个方法都在这样做,所以你总是销毁任何现有的数组。试着在这里做一些思考。在从不创建数组和每次创建数组之间有一个非常明显的快乐媒介:创建NSMutableArray仅一次
    【解决方案3】:

    已解决:问题出在 getAllEventText 方法中。

    allEventText 字符串在之前方法的 for 循环中不断替换自己的内容。

    我必须将 NSString 更改为 NSMutableString 并使用 append 方法添加到现有字符串,而不是替换其内容。

    所以我改变了方法如下,它现在可以工作了:

    -(NSString*) getAllEventText {
    
    NSMutableString* allEventText = [NSMutableString stringWithCapacity:150];
    
    // loop through NSMutableArray calling each Event's getEventText method using a for loop
    
    for (int i=0; i<[_scheduledEvents count]; i++) {
    
        [allEventText appendFormat:@"Event %d: %@\n", i+1, [_scheduledEvents[i] getEventText]];
    
        NSLog(@"%@", [_scheduledEvents[i] getEventText]);
    
    }
    
    // return concatenated string
    
    return allEventText;
    
    }
    

    也非常感谢 metronic 和 matt 建议我需要将 MSMutableArray 初始化程序从 addNewEvent 方法中移开!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多