2
votes

I am following an exercise from Aaron Hillegass's Cocoa book - chapter about Core Data. I have a document-based application that saves car(s) data into an array controller, it then uses bindings... The problem is that I have a date picker, and I want to initialize it to today's date as soon as a new car is added, so we're subclassing NSArrayController's newObject method. But, it always shows 2/12/1982! The NSLog inside the newObject method is not called. What am I (or book) missing?

CarArrayController.h

#import <Foundation/Foundation.h>

@interface CarArrayController : NSArrayController

@end

CarArrayController.m

#import "CarArrayController.h"

@implementation CarArrayController

- (id)init  //this is not called!
{
    self = [super init];
    if (self) {
        NSLog(@"in init");
    }
    return self;
}

-(id)newObject {   // not called either
    id newObj = [super newObject];
    NSDate *now = [NSDate date];
    [newObj setValue:now forKey:@"datePurchased"];
    NSLog(@"yep");
    return newObj;
}

@end

MyDocument.xib

Has an instance of NSArrayController, its Custom Class name is set to CarArrayController.

PS: For my Array Controller in MYDocument.xib, "Prepares Content" button is checked, so automaticallyPreparesContent should be set to YES...?

3
Have you set the Class Name/Entity Name for the array controller? - jscs
Oops, fixed it, thanks. The big problem is still there. :-( - janeh
@JoshCaswell, for the array controller, in MyDocument.xib, I set mode: Entity Name, entity Name: Car (that is the name of the entity in my .xcdata... file) - janeh

3 Answers

1
votes

I think there is a bug in Xcode 4.2, there is a thread on that in bignerdranch's forum: http://forums.bignerdranch.com/viewtopic.php?f=183&t=3465

Somehow Xcode doesn't realize that I changed the Array Controller to my custom class. To get it to work, I first added the initWithcoder method, then archived the application, then went back and deleted the initWithCoder method (going back to my original code), and now it works! People in the thread above propose other solutions that don't make sense… I'll assume it's a bug…

1
votes

To complement janehouse's answer, I had the same issue in the same book, albeit in the later fifth edition using Swift. Reading through that forum link, I found this post from riceboy which worked for me:

I think it is a bug.

For my part I had the same issue. What I did was:

1 - on "Textual Date Picker With Stepper" > "Value" tab, I unchecked the "Bind to Cars" checkbox.
2 - CMD+Shift+K to clean the project
3 - CMD+Shift+B to build the project
4 - Run it and close it
5 - Back on "Textual Date Picker With Stepper" > "Value" tab, I checked the "Bind to Cars" checkbox.
6 - Repeated step 2 to 4 then it worked...

Be sure that the class of your "Cars" controller is set to CarArrayController

I can only make the assumption that because we created the binding before setting our NSArrayController instance to the subclassed CarArrayController, those changes don't get propagated to the original bindings.

0
votes

To set default values on new instances of core data entities, you would be better off overriding awakeFromInsert in your managed object subclass. Set the default values there instead.

As to why your overridden method is not being called, I can only assume that you have made a subclass of NSArrayController but are somehow not using it? How does the controller show up if you log it?