Data Source Challenge-My Solution


#1

Hi all,

I did the basic data source challenge today, nothing fancy. I am liking how Xcode 4 works with IB and the Assistant Editor though.

AppDelegate.h

[code]#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate>
{
NSMutableArray *_taskList;
}

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *taskEntryField;
@property (weak) IBOutlet NSTableView *taskTableView;

  • (IBAction)addTask:(id)sender;

@end
[/code]

AppDelegate.m

[code]#import “AppDelegate.h”

@implementation AppDelegate

@synthesize window = _window;
@synthesize taskEntryField = _taskEntryField;
@synthesize taskTableView = _taskTableView;

// Actions

  • (IBAction)addTask:(id)sender {
    // Create an instance of our task list array if it doesn’t exist
    if (!_taskList) {
    _taskList = [NSMutableArray array];
    }

    // Add the task to the end of the array
    NSString *theTask = [_taskEntryField stringValue];
    [_taskList addObject:theTask];

    // Refresh the table view
    [_taskTableView reloadData];

}

// Table View Data Source Delegate Methods

  • (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
    {
    return (NSInteger)[_taskList count];
    }

  • (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {
    NSString *task = [_taskList objectAtIndex:row];
    return task;
    }

@end[/code]

Comments?


#2

Looks good!

Adam


#3

Very similar to my solution. The only real difference was that I initialised my array in the init method and put a basic check to ensure the item was at least one character long before adding it to the array.

#import "DataSourceAppDelegate.h"

@implementation DataSourceAppDelegate

@synthesize window = _window;
@synthesize textField = _textField;
@synthesize tableView = _tableView;

- (id)init
{
    self = [super init];
    if (self)
    {
        _toDoList = [NSMutableArray array];
    }
    return self;
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tv
{
    NSLog(@"ToDo list count: %lu", [_toDoList count]);
    return (NSInteger)[_toDoList count];
}

- (id)tableView:(NSTableView *)tv
        objectValueForTableColumn:(NSTableColumn *)tableColumn 
                                row:(NSInteger)row
{
    NSString *v = [_toDoList objectAtIndex:row];
    return v;
}

- (IBAction)addToDoItem:(id)sender 
{
    NSString *toDoItem = [_textField stringValue];
    
    if ([toDoItem length] > 0)
    {
        [_toDoList addObject: toDoItem];
        [_tableView reloadData];
        [_textField setStringValue:@""];
    }
}
@end

#4

Good idea about validating the data!

I allocated my array in the action method as I avoid allocating memory until I actually need it.


#5

Yeah, I think allocating the array memory only when needed is a good choice in this case.

I guess if the array could be accessed for the first time in a number of places within the class, putting it in the init would be the safety choice.


#6

Here’s my solution

AppController.h

[code]@interface AppController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
{
NSMutableArray *toDoItems;
}

@property (weak) IBOutlet NSTextField *textField;

@property (weak) IBOutlet NSTableView *toDoTableView;

  • (IBAction)createNewItem:(id)sender;

@end
[/code]

AppController.m

[code]@implementation AppController

@synthesize textField;
@synthesize toDoTableView;

  • (IBAction)createNewItem:(id)sender {

    if (!toDoItems) {
    toDoItems = [NSMutableArray array];
    }

    NSString *item = [textField stringValue];

    if (![item isEqualToString:@""]) {
    [toDoItems addObject:item];
    [toDoTableView reloadData];
    }

}

  • (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
    {
    return [toDoItems count];
    }

  • (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {
    return [toDoItems objectAtIndex:row];
    }

  • (void)tableView:(NSTableView *)tableView
    setObjectValue:(id)object
    forTableColumn:(NSTableColumn *)tableColumn
    row:(NSInteger)row
    {
    [toDoItems replaceObjectAtIndex:row withObject:object];

}

@end
[/code]