addObjects只将最后一个对象添加到NSMutableArray

问题描述:

我正在制作一个Schedule类并尝试在ViewController的循环中输出所有事件。我创建了一个Event类和Schedule类。我正在循环彻底NSMutableArray获取所有事件的文本。我的问题是,当我在Schedule.m文件中的addNewEvent方法时,我用通过addObject添加的最后一个对象覆盖我的NSMutable阵列。我的目标是将所有事件对象逐个添加到数组中并显示其文本。如果我可以为事件对象设置单独的ID,这也会很好。我知道我可能需要循环通过addNewEvent方法中的某些东西,当我将对象添加到可变数组中时,我不知道通过什么。我也认为也许我在错误的地方初始化了NSMutableArray(这是Schedule类的属性),但是如果我在其他地方移动初始化器,它会给出一个错误。addObjects只将最后一个对象添加到NSMutableArray

请帮我解决这个问题。任何帮助都感激不尽!

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

Event.h:

@interface Event : NSObject 

@property int eventId; 

@property NSString * eventTitle; 

@property NSString * eventDescription; 

@property NSDate * eventDate; 

-(void) logEvent; 

-(NSString*) getEventText; 

@end 

Event.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 

要重新初始化scheduledEvents每次addNewEventWithTitle:Description:andDate被调用。

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

+0

它不允许我这样做。当我这样做时,Xcode说:“使用未声明的标识符'_scheduledEvents'。” – PunainenAurinko

+0

好的,然后将该代码移动到schedule.m文件中的init方法 – metronic

+0

你的意思是做这样的事情: - (instancetype)init { self = [super init]; (self){ \t \t _scheduledEvents = [[NSMutableArray alloc] init]; } return self; }?当我这样做时,它仍然只输出最后一个对象到我的ViewController视图。 – PunainenAurinko

问题是这样的线:

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

根据定义,如果_scheduledEvents已经具有任何值(现有阵列),该线路破坏该值并用新的空数组替换它。所以运行你的addNewEvent...方法的结果将总是_scheduledEvents最终只包含这一个事件。

+0

是的,我知道我为数组放置初始值设定项存在问题。如果我删除你指向的那一行,什么都不会输出到我的ViewController视图。利用现在的行,输出最后添加的对象。 – PunainenAurinko

+0

我刚才解释说。毕竟,如果你没有在_some_点将一个空的NSMutableArray放入'_scheduledEvents'中,那么将不会有一个,所以没有什么可以添加任何东西并且什么也没有发生。但是_you_每次调用这个方法都会这样做,所以你总是会销毁任何现有的数组。试着在这里做一些思考。在_never_创建数组和创建数组之间有一个非常明显的快乐媒介_every_ time:创建NSMutableArray _just once_! – matt

解决:问题出在getAllEventText方法。

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

我不得不把的NSString更改为的NSMutableString和使用追加方法添加到现有的字符串,而不是取代它的内容。

所以我改变了方法如下所示,现在的作品:

-(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和马特的建议,我需要从addNewEvent方法移开MSMutableArray初始化!