updating cell value in table column not working

Hi all,

I know I have done this before but have been in OBJ c learning for a while…

I have a table view with columns for file paths and I want the first column to show the file icon. This works if I initially go through the array controllers values and set it there but there is a problem there (another post) so I want to use the delegate methods. tableView_objectValueForTableColumn_row_ is being called and the values are working but the icon is not being set for the icon column. The numberOfRowsInTableView_ is not being called. I have set the applescript class as the delegate and datasource but have not set up a datasource object since I am using array controllers ( like “sourcefs” below ) for all the tables.

I know I have done this before but am missing something?

Thanks in advance. And thanks Shane for the NSClassFromString in another post - it seems to be working.

 on tableView_objectValueForTableColumn_row_(aTableView, aColumn, aRow)
        
        if aColumn's identifier as string = "fileicon" then

            set thePath to sourcef's arrangedObjects()'s objectAtIndex_(aRow)'s valueForKey_("pathtofile")
            log thePath
            set theValue to NSWorkspace's sharedWorkspace()'s iconForFile_(thePath)
            log theValue

            return theValue

        end if
        
 end tableView_objectValueForTableColumn_row_
    
 on numberOfRowsInTableView_(aTableView)
        log "calling number of rows"
        log sourcef's arrangedObjects()'s |count|()
       return sourcef's arrangedObjects()'s |count|()
 end numberOfRowsInTableView_

Hi,

I recommend to do it object oriented with a custom class and bindings. The custom class requires ARC.

Create a Objective-C class named ASFileClass
replace the contents of the .h file with


#import <Foundation/Foundation.h>

@interface ASFileClass : NSObject

@property (copy) NSString *filePath;

- (id)initWithPath:(NSString *)path;

@end


replace the contents of the .m file with


#import "ASFileClass.h"

@implementation ASFileClass

+ (NSSet *)keyPathsForValuesAffectingFileImage
{
	return [NSSet setWithObject:@"filePath"];
}

- (id)initWithPath:(NSString *)path
{
    self = [super init];
    if (self) {
        _filePath = path;
    }
    return self;
}

- (NSImage *)fileImage
{
    return [[NSWorkspace sharedWorkspace] iconForFile:self.filePath];
}

@end

bind the value of the icon column to the array controller > arrangedObjects > Key Path fileImage
bind the value of the file path column to the array controller > arrangedObjects > Key Path filePath

in ASOC, add an object of the custom class with


 set fileClassInstance to current application's ASFileClass's alloc()'s initWithPath_("/path/to/file.ext")
 sourcef''s addObject_(fileClassInstance)

the icon will be updated automatically every time the path is changed

Thanks Stefan,

The problem all stemmed from my app crashing on launch and errors reported from users. It has all been working fine but suddenly on os 10.8.2 1n3 10.8.3 garbage collection seems to be stumbling. Perhaps they are really meaning it about “deprecated.”

Thread 5 Crashed:: Dispatch queue: Garbage Collection Work Queue
0   libauto.dylib                 	0x00007fff98d1661a auto_fatal + 202
1   libauto.dylib                 	0x00007fff98d24b2a Auto::Zone::handle_overretained_garbage(void*, int, int) + 138
2   libauto.dylib                 	0x00007fff98d251bd Auto::Zone::free_garbage(unsigned long, void**, unsigned long, void**, unsigned long&, unsigned long&)

I upgraded to ARC and it is working again fine but I need backwards compat to 10.7 at least. So I think the problem stems from those file images in the table view. Before, I would cycle through the path column and add in the images in the image column at launch time, then remove the images at quit. Crazy I know but I couldn’t handle archiving the images in ASOC when I started this. But other errors seem to be pointing to the image loading so I am trying to doit now through bindings as you are suggesting. STill not sure why it isn’t working with the delegate methods but perhaps because the table is tied up to array controller and not a datasource…


-[backupCAppDelegate applicationWillFinishLaunching:]: NSImageCell's object value must be an NSImage. (error -10000)
3/23/13 3:59:58.753 PM com.apple.launchd.peruser.501[140]: ([0x0-0x1ea1ea].com.rdutoit.backupList[2420]) Job appears to have crashed: Segmentation fault: 11

Can I use your method with the older garbage collection on, at least for a while - I have a big user base with pre ARC_ASOC OS’s.

Looks like an elegant solution though.

Rob

Stefan,

Unfortunately I don’t think I can use custom objects since I have an existing app out there which uses a plist of NSDictionaries to store the values of the table view. Also there are about twenty values (for myriad options for the files) bound through the selection on another table. It’s all hooked up through bindings and array controllers.

I am back to finding a way to just set the image cell for each row via the filePath column and I can’t think of any other way but the delegate method tableView_objectValueForTableColumn_row_(…)

I even tried value transformer and had the image cell column hold the path which gets converted to the image on the fly. No luck. It still seems like I am missing something simple to get the image returned to show up in the image column.

Rob

I got it working. Had to trash the table view methods in the ASOC class and rewrite in OBJ C class. Then I updated the array controller for the image column key instead of just returning the value to the tableView_objectValueForTableColumn_row_ method. I don’t know why the difference - I tried all that for two days in the ASOC class with no luck.

What is interesting though is that these Garbage Collector retain errors started appearing in OS 10.8.2 and 10.8.3. After the next OS release I may throw in the towel and go pure ARC.

Thanks everyone, Rob

I’ve never used Garbage Collection, but probably it’s sufficient to simply add a finalize method
and slightly change the initializer


@implementation ASFileClass

+ (NSSet *)keyPathsForValuesAffectingFileImage
{
	return [NSSet setWithObject:@"filePath"];
}

- (id)initWithPath:(NSString *)path
{
    self = [super init];
    if (self) {
        self.filePath = path;
    }
    return self;
}

- (void)finalize
{
	self.filePath = nil;
	[super finalize];
}


- (NSImage *)fileImage
{
    return [[NSWorkspace sharedWorkspace] iconForFile:self.filePath];
}

@end