appending image cells in table view

That doesn’t make a difference in my project, both lines cause the error “NSImageCell’s object value must be an NSImage”. Only iterating through the images and loading the image into the data cell directly seems to work.

Jon

You can see the error in this amended project:

http://homepage.mac.com/jonn8/as/dist/image_cells_append.sit

Jon

So I have an interest in making this work out… I am doing it in the standard: “make new data row … set contents of data cell …” kind of order and it works, but I am getting a “the variable result is not defined” in my log file the first time I add an item, but the mystery is that my code neither has a log statement, nor uses the result variable… :shock: … I can’t debug this statement because it’s a script closure I generate for a menu item at run time (see my plugins how to thread…)… there is a couple other strange issues poping up. I think it is related to creating the row without having the image in place at the time I make the row…

Okay, here’s what i got. It’s still not what i want though.
I want to be able to make a data row using the append command.
if anyone has any more ideas, i’d like to know.


--Assume that there's a table view called tvdata (inside svData), in a window called frmMain
--frmMain has a Awake from nib handler.  There is a .icns file in the project called "Green"
--There's 2 columns called Pic and description.  Pic is a image cell.

on awake from nib theObject
	if name of theObject is equal to "frmMain" then
		set theSource to missing value
		set newRow to missing value
		set theSource to make new data source at the end of data sources with properties {name:"dsData"}
		tell table view "tvData" of scroll view "svData" of window "frmMain"
			make new data column at the end of data columns of theSource with properties {name:"Pic"}
			make new data column at the end of data columns of theSource with properties {name:"Description"}
		end tell
		set data source of table view "tvData" of scroll view "svData" of window "frmMain" to theSource
		set newRow to make new data row at the end of data rows of theSource
		set contents of data cell "Pic" of newRow to load image "Green"
		set contents of data cell "Description" of newRow to "My Custum Icon"
		tell table view "tvData" of scroll view "svData" of window "frmMain" to update
	end if
end awake from nib

Does this actually still work in the current version of xcode?

For me, the NSButtonCell works just fine, but I cannot get the NSImageCell to actually load an image.

when the cell trys to draw I get this…

NSImageCell's object value must be an NSImage.

Here’s how I try to implement it…

set theTable to table view id 5 of scroll view id 4 of view id 3 of tab view id 2 of window id 1
set theDataSource to data source of theTable
set theDataRow to make new data row at end of data rows of theDataSource
tell theDataSource
    make new data column at the end of the data columns with properties {name:"valid_name"}
    make new data column at the end of the data columns with properties {name:"file_name"}
    make new data column at the end of the data columns with properties {name:"file_path"}
end tell
set contents of data cell "valid_name" of theDataRow to "myImage"

in IB I have place the NSImageCell into the first column.

In your code, you have the line…

set contents of data cell "valid_name" of theDataRow to "myImage"

“myImage” is a string, which is certainly not an NSImage. You probably mean…

set contents of data cell "valid_name" of theDataRow to myImage

If that deosn’t resolve things for you, this worked for me…

property theDataSource : null
property TableView : null

on awake from nib theObject
	if name of theObject is "TableView" then
		set TableView to theObject
		
		set theDataSource to make new data source at end of data sources with properties {name:"TableViewDataSource"}
		set data source of theObject to theDataSource

		tell theDataSource
			make new data column at the end of the data columns with properties {name:"Icon"}
			make new data column at the end of the data columns with properties {name:"Text"}
		end tell
	end if
end awake from nib

on clicked theObject
	if name of theObject is "AddRow" then
		set theRow to make new data row at the end of the data rows of theDataSource
		set tmpImage to (load image "Proxy_File")
		set content of data cell "Icon" of theRow to tmpImage
		delete tmpImage
		set content of data cell "Text" of theRow to "Some text"
	end if
end clicked

Discussion:
While apple’s data source docs tout datasources as ‘all that and a bag of chips’, I find them confusing and counterproductive… especially when working with table views (vs. outline views). The only advantage to using a data source is in getting the freebie feature of column sorting. If you don’t need table column sorting then I’d recommend that you pitch data sources out the window and stick with using ‘cell value’ and ‘number of rows’ to manually build your tables. This is standard practice in obj-c, and I find it to be more straightforward. With tables, you’re starting with a source list anyways, so why bother building a data source out of it and then working with that when you can just access the list items directly by row index?

Another thing to note is the 3 lines in my code where you load, set, and then delete the image used in the data cell. When you issue a “load image…” command, it retains the image in memory. If you are building a list of 100 items in your code that all use the same icon, issuing the load image command on the same image 100 times will result in 100 copies of the same image saved into your application’s memory space. It’s best to load the image, set it in the data cell, the delete it right away. When you set the image of the data cell, the data cell retains it’s own copy of the image, so the one you loaded is no longer needed.

Hope these help you get it figured out and also cleans up your implementation a bit.
j

Hi I have tried the load, set, and then delete, for when I load an image into my table view image cell.
But the memory does not recover . It appears the delete is not actually deleting the image in memory…

Does anyone have a clue why this would be…
This is the part of the code which is in a repeat loop for each image (in a on drop handler)


set tmpImage to (load image theItem)
				set contents of data cell "image" of theDataRow to tmpImage
				
				delete tmpImage
				set contents of data cell "file name" of theDataRow to theName

Many thanks.

Anyone!!

I experienced a similar behavior in one of my apps. It happened when I had an image view and I would quickly change the image in that image view… sometimes the images wouldn’t be deleted (released). This is the code I used to handle that. You could probably adapt it for your use. Basically I found that I could see all of the images that were in memory for the image view using set theImages to images. A list of the current images is returned. Since I only had one image view I only required one image to be in that list. As such if I found more than one I repeated through that list and deleted them again… except the last one which is the one that I needed.

set oldImage to call method "image" of (image view "iv" of scroll view "sv" of window nameMainWindow)
		set newImage to load image (item theCounter of posixFileList)
		try
			delete oldImage
			set imageCount to count of images
			if imageCount > 1 then -- when switching between large images fast, images can build up... so we delete them to free the memory
				set theImages to images
				repeat with i from 1 to (imageCount - 1) -- the last image in the list of images is always newImage, so we don't delete that
					delete (item i of theImages)
				end repeat
			end if
		end try

Hi , Thanks

I did try something similar, I got the count of items in tmpImage, but the odd thing is when after the delete tmpImage


set g to count of items in tmpImage
				log g
				--> 1 
				delete tmpImage
				set g to count of items in tmpImage
				log g
				-->Can't get image id 65. (-1728)
				e

I get an error if I try to check the count again rather than 0. ?

Try it as I suggested. Don’t count tempImage…

set theImages to images
set imageCount to count of theImages

Then repeat through theImages and delete whatever images you don’t need.

Thanks for your continued help.

The problem is, I am adding images to a table view with image cells.

I drag and drop new images on to the table. It displays a thumbnail in the image column and a file name in the file name column.
Each image is loaded via a repeat loop one at a time.
the repeat loop iterates basically :

repeat with theItem in theFiles
				set theDataRow to make new data row at end of data rows of theDataSource
				
				set theName to displayed name of (info for ((POSIX file theItem)))
				
				
				set tmpImage to (load image theItem)
				set contents of data cell "image" of theDataRow to tmpImage
				
				delete tmpImage
				set contents of data cell "file name" of theDataRow to theName
				
			end repeat

So there is only one image to ever purge at a time. ??
It maybe my brain is fried, but i do not see a way to incorporate your script…

I would try this… basically after you come out of the repeat loop you have all the images placed in the table that you want. Therefore you know how many images should actually be in memory, which is either the count of theFiles if that’s all you’re showing in the table or it’s the count of rows in the table. My example uses the count of theFiles. Use this after the repeat loop or in an “on idle” handler. I’d probably try an “on idle” handler so that your project continually makes sure that there are no extra images in memory.

try
set imageCount to count of images
if imageCount is greater than count of theFiles then
set theImages to images
repeat with i from 1 to (imageCount - (count of theFiles))
delete (item i of theImages)
end
end
end

This assumes that the line set theImages to images will give you all of the images in memory… which in my image view application it did. You can log theImages to see the list of the images to make sure.

Hi ,
thanks again, but that does not work
image cells…:mad:

.

The memory use stays the same. and goes up rather than down… So I added a simply say to see if the count actually got to the delete. It does not get past 1

try
				set imageCount to count of images
				say 1
				if imageCount is greater than (count of theFiles) then
					say 2
					set theImages to images
					repeat with i from 1 to (imageCount - (count of theFiles))
						delete (item i of theImages)
					end repeat
				end if
			end try

try
				set imageCount to count of images
				say 1
			
				if imageCount is greater than 0 then
					say 2
					set theImages to images
					repeat with i from 1 to (imageCount) 
						say 3
						delete (item i of theImages)
					end repeat
				end if
			end try


So a little bit more playing and I can get to 3 in this. It will say 3 the same amount of times as the number of images I throw on.
i then added a delete images within the other repeat loop ( just after I load and add the image).
Than i only get to 1.

This tells me the images in memory are actually getting deleted.

So why is the Real memory and virtual memory not being released??

Hi All,

The images in the image cells are being deleted by the looks of it using regulus6633’s bits of code to test.

But I stiil have not solved the problem of why the memory is not being released.

Does anyone have any ideas of what may it may be?

Thanks

Does any one have a clue to this memory problem, Surely some else has come across this before!! is it a bug in ASS?

Failing an answer. is there a clear cut way for a pure novice such as myself to be shown how to add the images to the cell using object c in the applescript app.
So I can use alloc and release?? ( P.s should I start a new thread ?)

Many thanks
Mark

alloc is automatically done when you load your image,
but you need to delete it after use (no autorelease in AS) or you memory will increase!!!

make a test with big pictures, and take a look to Activity Monitor (memory use), it’s awfull

I found this subroutine in my app

-- ???: COMMUN - ReleaseImage
on ReleaseImage(l_ImageView) --release d'une view image (donner la view image comme arg)
	-- http://developer.apple.com/documentation/AppleScript/Reference/StudioReference/sr3_app_suite/sr_app.html#//apple_ref/doc/uid/20011217-ASKApplicationSuite.Commands.LoadImage
	
	-- Get a reference to the old image, if there is one
	set oldImage to image of l_ImageView
	
	-- Delete the old image (use try block in case no image)
	try
		delete oldImage -- release
	end try
	
	return
end ReleaseImage

bye

Hi MC,

I do not think you read any of my previous posts.
I know all about the load and delete image. But I am still getting a memory issue where the memory increases even though the loaded images are deleted.

So my question and request for help is:

Does any one have a clue to this memory problem, Surely some else has come across this before!! is it a bug in ASS?

Failing an answer. is there a clear cut way for a pure novice such as myself to be shown how to add the images to the cell using object c in the applescript app.
So I can use alloc and release?? ( P.s should I start a new thread ?)

Many thanks
Mark

sorry, should be my bad level of english
With this code I don’t have memory problem anymore (and I sometimes use hundred of files, but I never try with more than 200)

personnaly I didn’t manage to transfer “image AS id” to Cocoa, so I failed to release it in Cocoa

bye