views:

45

answers:

1

Hi all. I am trying to learn cocoa and have a few problems with KVC and bindings. I have a nstableview with three columns; "checkbox", "text", "icon". The values of each column is binded to an arraycontroller using KVC. When program is launched the rows and columns are correctly filled into the tableview according to the values in the array. I can click a row and correctly print the content of that row using something like this:

 - (IBAction)fileTableViewSelected:(id)sender{
    NSInteger r; 
    NSDate    *fModOne;
    id object;

    r = [[NSNumber numberWithInt:[sender selectedRow]] intValue];
    object = [arrayIntersect objectAtIndex:r];

    fModOne = [object valueForKey:@"fileModifiedDirOne"];
    NSLog(@"Date found in row is %@",fModOne);
}

My problem is when I try to click the checkbox in column one and change the value of the box. Initially, the value of the checkbox is set to 1 using the arraycontroller which works fine, but when I want to change the value of the checkbox of a specific row to 0 by clicking on it the program crashes. When the box is clicked an action is correctly called and this is where I thought I could simply change the value of my objects BOOL by calling:

[object setValue:[NSNumber numberWithBool:NO] forKey:@"doSync"];

My setters and getters for the BOOL doSync is defined as:

@property(nonatomic, readwrite) BOOL doSync;
@dynamic doSync;


- (void)setDoSync:(BOOL) value{
NSLog(@"setting dosync %i", value);
doSync = NO;
 }

 - (BOOL)doSync{
return doSync;
 }

I have searched everywhere for a solution to my problem, but I am unable to find any examples of how to use checkboxes in tableview using KVC and bindings. I appreciate any help I can get on this and I would appreciate any examples I could take a look at. Cheers and thanks! Trond

A: 

You don't need to implement this yourself as an action. Just bind the column through your array controller's arrangedObjects to the doSync property of the model objects.

If you don't want to use Bindings, you still shouldn't implement it as an action. Instead, be the table view's data source and respond to the message the table view will send you to change one of the values.

@dynamic doSync;

There's no reason to have this if you turn around and implement the accessors for that property in the same class.

If this is a managed-object class and the property is an attribute of the entity, then your accessors should send [self willAccessValueforKey:] before and [self didAccessValueForKey:] after accessing the instance variable. If that's all they do, then you should not implement the custom accessors at all; cut them out and have @dynamic alone.

- (void)setDoSync:(BOOL) value{
    doSync = NO;

That's not setting the property to the value passed in.

Peter Hosey
Thanks for your answer Peter. I followed your suggestions but I am still experiencing crash in application when clicking the checkbox. I think the problem is with the setter that looks like this:- (void)setDoSync:(BOOL)newDoSync { [self willAccessValueForKey:@"doSync"]; doSync = newDoSync; [self didAccessValueForKey:@"doSync"];} I think I do everything else correctly by binding the column to the attribute (doSync) of the object. The inital vieew of table looks good with values of the checkboxes set to 1. Suggestions for how to implement the setter for a boolean attribute is appreciated
Trond Kristiansen
As I said, you don't need to implement that accessor. Cut it out entirely and use `@dynamic` alone. If it still crashes, ask a new question and include the crash log in it.
Peter Hosey