The document for -[NSInvocation retainArguments] tells me:
"If the receiver hasn’t already done so, retains the target and all object arguments of the receiver and copies all of its C-string arguments. ... Newly created NSInvocations don’t retain or copy their arguments, nor do they retain their targets or copy C strings. You should instruct an NSInvocation to retain its arguments if you intend to cache it, since the arguments may otherwise be released before the NSInvocation is invoked."

So I decided to -retainArguments, and presumed that this meant I was supposed to release the target and arguments when I was done with them. But I thought it was odd that the documentation did not say so explicitly, so I did a little experiment, and learned that - retainArguments also adds them to the autorelease pool! Presumably (I hope) this happens when and in the thread where the invocation is invoked.

The code and results are below. Whether -retainArguments is commented out or not, the target (Target) and the argument (StringWrapper) both get deallocced just the same. If -retainArguments is commented out, the final NSLog() does cause a crash, but that is expected since in this case the target and argument have not been placed in the autorelease pool by the action of -retainArguments.

If anyone sees anything wrong with my explanation, please reply. I'm using NSInvocation alot.


------ CONSOLE OUTPUT  ------

2009-07-31 23:08:56.848 Test[48825:10b] retainCounts: target=1 stringWrapper=1 2009-07-31 23:08:56.854 Test[48825:10b] retainCounts: target=2 stringWrapper=2
2009-07-31 23:08:56.860 Test[48825:10b] Hello
2009-07-31 23:08:56.861 Test[48825:10b] retainCounts: target=2 stringWrapper=2 2009-07-31 23:08:56.862 Test[48825:10b] retainCounts: target=1 stringWrapper=1
2009-07-31 23:08:56.864 Test[48825:10b] dealloccing Target
2009-07-31 23:08:56.871 Test[48825:10b] dealloccing MyString

------ CODE ------

#import <Cocoa/Cocoa.h>

@interface StringWrapper :NSObject{
    NSString* string ;
}

@property (retain) NSString* string ;
- (id) initWithString:(NSString*)string ;

@end

@implementation StringWrapper

@synthesize string ;
- (id) initWithString:(NSString*)string_ {
    self = [super init];
    if (self != nil) {
        [self setString:string_] ;
    }
    return self;
}

- (void)dealloc {
    NSLog(@"dealloccing MyString") ;
    [string release] ;
    [super dealloc] ;
}

@end


@interface Target : NSObject {

}

- (void)logThis:(StringWrapper*)what ;

@end

@implementation Target

- (void)logThis:(StringWrapper*)what {
    NSLog([what string]) ;
}

- (void)dealloc {
    NSLog(@"dealloccing Target") ;
    [super dealloc] ;
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init] ;

    Target* target = [[Target alloc] init] ;
    SEL selector = @selector(logThis:) ;
NSMethodSignature* methSig = [target methodSignatureForSelector:selector] ;

NSInvocation* invoc = [NSInvocation invocationWithMethodSignature:methSig] ;
    [invoc setTarget:target] ;
    [invoc setSelector:selector] ;
StringWrapper* stringWrapper = [[StringWrapper alloc] initWithString:@"Hello"] ;
    [invoc setArgument:&stringWrapper
               atIndex:2] ;

    NSLog(@"retainCounts:  target=%d  stringWrapper=%d",
          [target retainCount],
          [stringWrapper retainCount]) ;

        // Here's the retainArguments which may be commented out:
        [invoc retainArguments] ;
    NSLog(@"retainCounts:  target=%d  stringWrapper=%d",
          [target retainCount],
          [stringWrapper retainCount]) ;

    [invoc invoke] ;
    NSLog(@"retainCounts:  target=%d  stringWrapper=%d",
          [target retainCount],
          [stringWrapper retainCount]) ;

    [target release] ;
    [stringWrapper release] ;

    NSLog(@"retainCounts:  target=%d  stringWrapper=%d",
          [target retainCount],
          [stringWrapper retainCount]) ;

    [pool release] ;
}

_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to