开发者

NSArrayController and Key Value Coding

开发者 https://www.devze.com 2023-02-16 07:54 出处:网络
I am trying to populate a document based NSTableView and control it using the NSArrayController. I g开发者_如何学运维uess I understood the concepts of Key Value coding. However, I fear the NSArrayCont

I am trying to populate a document based NSTableView and control it using the NSArrayController. I g开发者_如何学运维uess I understood the concepts of Key Value coding. However, I fear the NSArrayController is not honoring the Accessor Search Pattern for Ordered Collections. Let me explain

I have a class Name Student as defined

#import <Cocoa/Cocoa.h>


@interface Student : NSObject {

    NSString* studentName;
    float marks;

}

//Accessor and mutators
@property (readwrite, copy) NSString* studentName;
@property (readwrite) float marks;

//Initializer - Init all resources
-(id) init;

//Dealloc - Release resources
-(void) dealloc;

@end

The implementation is

#import "Student.h"


@implementation Student

//Synthesize the accessors
@synthesize studentName;
@synthesize marks;

//Initializer - Init all resources
-(id) init
{
    self = [super init];
    if(self){
        studentName = @"New Student";
        marks = 0.0;
    }
    return self;
}

//Dealloc - Release resources
-(void) dealloc
{
    [studentName release];
    [super dealloc];
}

@end

MyDocument class is defined as follows which contains an NSMutableArray type instant variable

#import <Cocoa/Cocoa.h>

@class Student;

@interface MyDocument : NSDocument
{
    NSMutableArray* students;
}

//Initializers
-(id) init;

//Deallocators
-(void) dealloc;

//Creating the proxy object
-(id) mutableArrayValueForKey:(NSString *)key;

//Array controller uses keyvalue
//coding to call this 
-(void) insertObject:(Student*) s inStudentsAtIndex:(int) index;


@end

In IB, the Array Controller's attributes is set to Student object and its instance variables are added to the key. In the binding section, Content Array is bind to File Owner's which is an instance of MyDocument class. The model key path is set to the array name students

Here is the implementation of MyDocument

#import "MyDocument.h"
#import "Student.h"

@implementation MyDocument

- (id)init
{
    self = [super init];
    if (self) {

        students = [[NSMutableArray alloc] init];

    }
    return self;
}

-(void) dealloc
{
    [students release];
    [super dealloc];
}

//Array controller uses keyvalue
//coding to call this 
-(void) insertObject:(Student*) s inStudentsAtIndex:(int) index
{
    NSLog(@"Insert object is called");
}


//Creating the proxy object
-(id) mutableArrayValueForKey:(NSString *)key
{
    NSLog(@"Checking if NSArrayController is trying to create a proxy %@",key);
    return students;
}

My problem -(void) insertObject:(Student*) s inStudentsAtIndex:(int) index is never called. However, if I implement a function name -(void) setStudents:(Student*)s, that is called. -(id) mutableArrayValueForKey:(NSString *)key is just for debugging purpose; I wanted to see some part of the Key Value coding is working. The behavior is same with or without -(id) mutableArrayValueForKey:(NSString *)key

What am I missing ? I am on Mac 10.6.6 with XCode 3.2.5


Please read the Accessor Search Pattern for Ordered Collections section in here. Quoting the sentence

The receiver's class is searched for a pair of methods whose names match the patterns -insertObject:in<Key>AtIndex: and -removeObjectFrom<Key>AtIndex: (corresponding to the NSMutableArray primitive methods insertObject:atIndex: and removeObjectAtIndex: respectively), or methods matching the pattern -insert<Key>:atIndexes: and -remove<Key>AtIndexes: (corresponding to the NSMutableArrayinsertObjects:atIndexes: and removeObjectsAtIndexes: methods).

So you have to implement the PAIR. Your class should implement both -removeObjectFrom<Key>AtIndex: and insertObject:in<Key>AtIndex:


Based on what you're said, I'm not sure when insertObject: would be called. In IB, you bound the array controller to your NSMutableArray, so it doesn't know anything about your MyDocument class.

If you want some sort of notification of when a new student is added to your array, you would need to hook that up yourself. One way to do this is to handle the action from the UI yourself (such as if you have a New button), and in that handler add the object to your array, and do whatever other logic is required.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号