bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Fix NSMenu retainCount problem


From: Quentin Mathé
Subject: Re: [PATCH] Fix NSMenu retainCount problem
Date: Sat, 7 Feb 2004 17:28:11 +0100

Le 7 févr. 04, à 15:47, Alexander Malmberg a écrit :

Quentin Mathé wrote:

the user shouldn't have to know the framework implementation. In other
terms, correct objective-c memory management needs to support this rule
: sending a message to an object should never induce increased retain
count for this object.

I don't think this rule should be adopted. It's blatantly false for a
huge number of methods.

Well... sure, I would not pretend it's THE rule. :-)

While I can see that it would be useful in some
odd cases, the huge number of exceptions would make it difficult to rely on. Cascading exceptions would make things even worse. For example, note
that methods implemented like:

-(NSString *) uppercaseString
{
        if (!self_contains_lowercase_characters)
                return [[self copy] autorelease];
        else
        {
                /* create new string, etc. */
        }
}

violate this rule and would have to rewritten in a less clear and less
efficient way.

I don't understand why this method violates this rule, because the retain count for self isn't modified, the method just returns a copy or a new instance and I said nothing about what the method can return... perhaps there is something screwed up in my thinking but I'm not seeing it.


The library should be free to autorelease objects. Library methods
should use their own autorelease pools if they autorelease a "large"
number of objects, and must always use one if the number of autoreleased
objects is unbounded. However, in the end, when the method returns, the
number of autoreleases on the objects that have been involved is
unspecified.

No problem with that. I'm just saying if you write :

[self retain];
blabla
[self autorelease];

you must use a local autorelease pool and release it at the end of the method.

If you're relying on exactly when -dealloc is called for an instance
(which should be very rare), you need to explicitly manage autorelease
pools to ensure that there are no pending autoreleases. Alternatively,
you can split out the necessary "invalidation" from the -dealloc (like
eg. -base's NSConnection).

Well I see your point... but for NSMenu, with this approach, I must write :

- (void)methodForContextMenuExample
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  NSMenu *menu = [[NSMenu alloc] initWithTitle:@"bip"];

  [menu addItem:menuItem];

[menu setMenuChangedMessagesEnabled:YES]; // to process the notifications still around
 [pool release]; // to release the notifications which retain the menu

  [menu release]; // now we are sure the menu will be deallocated

  // Now I can reuse menu Item
  menu = [[NSMenu alloc] initWitTitle:@"hop"];
  [menu addItem:menuItem];
}

Not very obvious... how will you explain to other developers a such pratice ? Specific documentation for each GNUstep classes ?

With Cocoa, to do the same thing, I just need to write :

- (void)methodForContextMenuExample
{
  NSMenu *menu = [[NSMenu alloc] initWithTitle:@"bip"];

  [menu addItem:menuItem];

  [menu release]; // we are sure the menu will be deallocated

  // Now I can reuse menu Item
  menu = [[NSMenu alloc] initWitTitle:@"hop"];
  [menu addItem:menuItem];
}

I prefer that, more obvious and clean...

Quentin.

--
Quentin Mathé
qmathe@club-internet.fr




reply via email to

[Prev in Thread] Current Thread [Next in Thread]