On Oct 16, 2011, at 00:23 , Gerriet M. Denkmann wrote:

> I have this code:
>               
> for( id aThing in someArray )
> {
>       if ( [ aThing respondsToSelector: @selector(setTitle:) ] )
>       {
>               [ self  replaceIn:              aThing 
>                               readSelector:   @selector(title) 
>                               writeSelector:  @selector(setTitle:) 
>                               withTable:              tableName 
>               ];
>       }
> }
> 
> 
> - (void)replaceIn: thing  readSelector: (SEL)selectorIn  writeSelector: 
> (SEL)selectorOut  withTable: (NSString *)tableName;
> {
>       NSString *key = [ thing performSelector: selectorIn ];
>       ...
>       NSString *rep = ...
>       [ thing performSelector: selectorOut withObject: rep ];
> }
> 
> Now, using Arc I am told that  "PerformSelector may cause a leak because its 
> selector is unknown".
> What I am supposed to do about this? I really want to have code without 
> warnings.

It's not always easy to directly translate code intended for one memory 
management model to another. Your code for the second method is (in some sense) 
unsafe, although it's easy for us to deduce its safety (in practice) from the 
code in the first method.

One solution for this kind of thing is to look for a way to do this using 
blocks. Often with blocks it isn't necessary to obscure types just so that you 
can route execution through a generic choke point.

Or, you can look much more carefully (on a case-by-case basis) at what you're 
really trying to accomplish, and look for a less hinky way. If the 'for' loop 
you've shown us really *is* your code, rather than a simplified example, I'd be 
inclined to do something like this:

        for (id aThing in someArray)
                if ([aThing respondsToSelector @selector (setTitle:)])
                        [aThing setTitle: [self replacementStringFor: [aThing 
title] withTable: tableName];

        - (NSString*) replacementStringFor: (NSString*) key
        {
                …
                NSString* rep = …
                return rep;
        }

That's assuming you want unfettered polymorphism for property "title". If 
things are actually a bit more organized, you might want to make a protocol 
that contains the "title" @property, and make some objects conform to the 
protocol, then write:

        for (id<MyTitleProtocol> aThing in someArray)
                if ([aThing conformsToProtocol: @protocol (MyTitleProtocol)])
                        aThing.title = [self replacementStringFor: aThing.title 
withTable: tableName];

These are pretty much random ideas for rewrites of your code, which you can pay 
no attention to. The point I'm trying to make is if you express a clearer 
intention *syntactically*, the issue that ARC raises might not even come up.

> Update:
> I guess Arc has no way to know, whether "selectorIn" is something like 
> "copy". 
> So I am quite willing to reassure it that "selectorIn" is always something 
> like title, stringValue, toolTip, etc. 
> I think I should declare the SEL as __attribute__((ns_returns_not_retained)).
> 
> But how exactly? There really should be some examples.

_______________________________________________

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