Hi, Thanks for this, I actually spotted that late last night and I refactored the code to read as below, but it still crashes if I do not retain the "iconImage":
- (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell forTableColumn:(NSTableColumn *)tableColumn item:(id) item { NSImage* iconImage; NSString* urlStr; ImageAndTextCell* myCell; ChildNode* myChildNode; if ([[tableColumn identifier] isEqualToString:COLUMNID_NAME] == NO) return; if ([cell isKindOfClass:[ImageAndTextCell class]] == NO) return; iconImage = nil; myChildNode = [item representedObject]; if (myChildNode == nil) return; if ([myChildNode class] != [ChildNode class]) return; if (myChildNode.isLeaf == YES) { urlStr = myChildNode.urlString; if (urlStr != nil) { if ([myChildNode.urlString hasPrefix:HTTP_PREFIX]) { myChildNode.nodeIcon = self.pURLImage; } else { iconImage = [[[NSWorkspace sharedWorkspace] iconForFile:urlStr] copy]; //Crashes without retain LogIfDave(@"Before Get File iconImage - retainCount: %ld",[iconImage retainCount]); myChildNode.nodeIcon = iconImage; //******* [iconImage release]; //** Crashes if Present LogIfDave(@"After set Item iconImage - retainCount: %ld",[iconImage retainCount]); } } } //** //** Check if it's a special folder (PLACES or BOOKMARKS), we don't want it to have an icon //** else { if ([self isSpecialGroup:myChildNode]) { myChildNode.nodeIcon = nil; } else { myChildNode.nodeIcon = self.pFolderImage; } } [myChildNode.nodeIcon setSize:NSMakeSize(kIconImageSize,kIconImageSize)]; myCell = (ImageAndTextCell*) cell; iconImage = myChildNode.nodeIcon; if (iconImage != nil) LogIfDave(@"Before set pTextCellImage - retainCount: %ld",[iconImage retainCount]); myCell.pTextCellImage = iconImage; // Crashes here if release above is present if (iconImage != nil) LogIfDave(@"After set Item pTextCellImage - retainCount: %ld",[iconImage retainCount]); } ————————————————————————————————————————— This is the Original from SourceView, the problem you spotted is in this code too, in that if item == nil, the code at the end will operate on a nil Object (item). - (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { if ([[tableColumn identifier] isEqualToString:COLUMNID_NAME]) { // we are displaying the single and only column if ([cell isKindOfClass:[ImageAndTextCell class]]) { item = [item representedObject]; if (item != nil) { if ([item isLeaf]) { // does it have a URL string? NSString *urlStr = [item urlString]; if (urlStr) { if ([item isLeaf]) { NSImage *iconImage; if ([[item urlString] hasPrefix:HTTP_PREFIX]) { iconImage = urlImage; } else { iconImage = [[NSWorkspace sharedWorkspace] iconForFile:urlStr]; } NSLog(@"outlineView: willDisplayCell: forTableColumn: item:"); NSLog(@"URL: %@",[item urlString]); [item setNodeIcon:iconImage]; } else { NSImage* iconImage = [[NSWorkspace sharedWorkspace] iconForFile:urlStr]; [item setNodeIcon:iconImage]; } } else { // it's a separator, don't bother with the icon } } else { // check if it's a special folder (PLACES or BOOKMARKS), we don't want it to have an icon if ([self isSpecialGroup:item]) { [item setNodeIcon:nil]; } else { // it's a folder, use the folderImage as its icon [item setNodeIcon:folderImage]; } } } // set the cell's image [[item nodeIcon] setSize:NSMakeSize(kIconImageSize, kIconImageSize)]; ImageAndTextCell *myCell = (ImageAndTextCell *)cell; myCell.myImage = [item nodeIcon]; } } } All the Best Dave > On 27 May 2015, at 12:52, Mark Wright <blue.bucon...@virgin.net> wrote: > > If you paste this in instead does it still crash?: > Apologies for changing the formatting and structure, I needed to change it up > to something I’m used to to read it better. > > There’s a problem with the main ‘else’ branch which would only execute if > ‘myChildNode’ is nil. > > This is how I’d have structured the variables and such so if it manages to > compile and doesn’t crash then I can only guess that there was some problem > with the re-using or back-assigning of the ‘iconImage’ variable in the bottom > few lines. > > > > - (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell > forTableColumn:(NSTableColumn *)tableColumn item:(id)item { > > if (![[tableColumn identifier] isEqualToString:COLUMNID_NAME]) > return; > > // we are displaying the single and only column > if (![cell isKindOfClass:[ImageAndTextCell class]]) > return; > > ChildNode *myChildNode = [item representedObject]; > if (myChildNode) { > if (myChildNode.isLeaf == YES) { > > NSString *urlStr = myChildNode.urlString; > if (urlStr) { > if ([myChildNode.urlString hasPrefix:HTTP_PREFIX]) { > myChildNode.nodeIcon = self.pURLImage; > } else { > NSImage *iconImage = [[NSWorkspace sharedWorkspace] > iconForFile:urlStr]; > myChildNode.nodeIcon = iconImage; > } > } > } > } else { > > //*********************************************************************** > //***** INVALID: myChildNode is nil here from the conditional above > ***** > > //*********************************************************************** > //** > //** Check if it's a special folder (PLACES or BOOKMARKS), we don't > want it to have an icon > //** > if ([self isSpecialGroup:myChildNode]) { > myChildNode.nodeIcon = nil; > } else { > myChildNode.nodeIcon = self.pFolderImage; > } > } > > // set the cell's image > [myChildNode.nodeIcon setSize:NSMakeSize(kIconImageSize, kIconImageSize)]; > > (ImageAndTextCell*)cell.pTextCellImage = myChildNode.nodeIcon; > } > > > > > >> On 27 May 2015, at 11:48, Dave <d...@looktowindward.com> wrote: >> >> Hi, >> >> Sorry, I wasn’t very clear, the VC is my existing VC with the Source Vice >> Code from “myViewController” code added so this had to be converted to use >> manual memory management. I also converted the other supporting classes >> although as you point out, I could have just set the compiler flag. >> >> Here are the property definitions from ChildNode: >> >> // BaseNide.h >> >> @interface BaseNode : NSObject <NSCoding, NSCopying> >> { >> } >> >> @property (nonatomic,retain) NSString* nodeTitle; >> @property (nonatomic,retain) NSImage* nodeIcon; >> @property (nonatomic,retain) NSMutableArray* children; >> @property (nonatomic,retain) NSString* urlString; >> @property (nonatomic,assign) BOOL isLeaf; >> >> >> // ChildNide.h >> >> @interface ChildNode : BaseNode >> >> ——————— >> >> Here are the property definitions from ImageAndTextCell: >> >> @property (nonatomic,retain) NSImage* >> pTextCellImage; >> >> These two are in the View Controller Itself: >> >> @property (nonatomic,retain) NSImage* >> pFolderImage; >> @property (nonatomic,retain) NSImage* >> pURLImage; >> >> Thanks for your help, I’ve worked on loads of Projects where I’ve had to >> convert to/from ARC, but never had a problem like this. I’ve obviously >> missed something, but I’ve been all over the code and it all looks fine. I >> am worried that the Analyser isn’t showing a problem though, I’ve come to >> rely on it quite a bit and the fact that I’ve seem it get it wrong a couple >> of times makes me wonder….. >> >> All the Best >> Dave >> >>> On 26 May 2015, at 19:34, Dave <d...@looktowindward.com> wrote: >>> >>> Hi, >>> >>> I’ve incorporated the Tree Controller in SourceView. SourceView shows a >>> Split View with a tree structure on the left and either shows the contents >>> of a URL or a List of Files on the right, depending on which item is >>> selected in the left view. >>> >>> The SourceView project is built using ARC, but my App uses Manual Memory >>> Management. When I moved the code over, I changed it to use release etc. >>> and changed any properties or iVar’s to use retain or assign. The problem >>> builds with no analyser warnings (which doesn’t mean as much as it used to, >>> because I’ve found that the Analyser in XCode 6.3 is buggy). >>> >>> When I run the App, it displays the Tree View fine and Populates the two >>> sections, but it crashes due to an over-release if I select a file based >>> item - I found this by using NSZombies - it gives the error: >>> >>> *** -[NSImage release]: message sent to deallocated instance 0x20e5b9fc0 >>> >>> I traced the problem down to the method copies below - please see comments >>> in code. I’ve stopped it crashing by adding a retain although it doesn’t >>> display the Files Correctly so there is something else wrong. I can’t >>> figure out why I need this extra retain since everything seems to balanced >>> without it. >>> >>> Any ideas how to debug this would be greatly appreciated. >>> >>> All the Best >>> Dave >>> >>> - (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell >>> forTableColumn:(NSTableColumn *)tableColumn item:(id) item >>> { >>> NSImage* iconImage; >>> NSString* urlStr; >>> ImageAndTextCell* myCell; >>> ChildNode* myChildNode; >>> >>> if ([[tableColumn identifier] isEqualToString:COLUMNID_NAME] == NO) >>> return; >>> >>> // we are displaying the single and only column >>> if ([cell isKindOfClass:[ImageAndTextCell class]] == NO) >>> return; >>> >>> iconImage = nil; >>> myChildNode = [item representedObject]; >>> if (myChildNode != nil) >>> { >>> if (myChildNode.isLeaf == YES) >>> { >>> urlStr = myChildNode.urlString; >>> if (urlStr != nil) >>> { >>> if ([myChildNode.urlString hasPrefix:HTTP_PREFIX]) >>> { >>> myChildNode.nodeIcon = self.pURLImage; >>> } >>> else >>> { >>> iconImage = [[[NSWorkspace sharedWorkspace] >>> iconForFile:urlStr] copy]; //Crashes without retain or if I remove the >>> copy and and release statement below >>> >>> LogIfDave(@"Before Get File iconImage - >>> retainCount: %ld",[iconImage retainCount]); >>> myChildNode.nodeIcon = iconImage; >>> //***** [iconImage release]; >>> //** Crashes if >>> Present!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! >>> >>> LogIfDave(@"After set Item iconImage - >>> retainCount: %ld",[iconImage retainCount]); >>> } >>> } >>> } >>> } >>> else >>> //** >>> //** Check if it's a special folder (PLACES or BOOKMARKS), we don't >>> want it to have an icon >>> //** >>> { >>> if ([self isSpecialGroup:myChildNode]) >>> { >>> myChildNode.nodeIcon = nil; >>> } >>> else >>> { >>> myChildNode.nodeIcon = self.pFolderImage; >>> } >>> } >>> >>> // set the cell's image >>> [myChildNode.nodeIcon setSize:NSMakeSize(kIconImageSize,kIconImageSize)]; >>> myCell = (ImageAndTextCell*) cell; >>> >>> iconImage = myChildNode.nodeIcon; >>> >>> if (iconImage != nil) >>> LogIfDave(@"Before set pTextCellImage - retainCount: %ld",[iconImage >>> retainCount]); >>> >>> //*** This line causes a crash if the [iconImage release]; statement above >>> is executed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! >>> >>> myCell.pTextCellImage = iconImage; >>> >>> if (iconImage != nil) >>> LogIfDave(@"After set Item pTextCellImage - retainCount: >>> %ld",[iconImage retainCount]); >>> } >>> >>> >>> _______________________________________________ >>> >>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >>> >>> Please do not post admin requests or moderator comments to the list. >>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >>> >>> Help/Unsubscribe/Update your Subscription: >>> https://lists.apple.com/mailman/options/cocoa-dev/dave%40looktowindward.com >>> >>> This email sent to d...@looktowindward.com >> >> >> _______________________________________________ >> >> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) >> >> Please do not post admin requests or moderator comments to the list. >> Contact the moderators at cocoa-dev-admins(at)lists.apple.com >> >> Help/Unsubscribe/Update your Subscription: >> https://lists.apple.com/mailman/options/cocoa-dev/blue.buconero%40virgin.net >> >> This email sent to blue.bucon...@virgin.net > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com