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

Reply via email to