On Oct 15, 2011, at 11:58 PM, 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.


ARC can't see the selector you pass to know if it conforms to the memory 
management policy implied by the -performSelector* calls, hence it reports this 
warning. If you called [thing performSelector:@selector(copy)] for example, you 
would leak. If you called [thing performSelector:@selector(release)] (not valid 
in ARC, but possibly if the selector is passed back by other means) you would 
over-release and crash.

In general the recommendation for something like this would be to replace this 
code with something safer, such as with blocks or protocols. Other solutions 
would involve either calling objc_msgSend() directly or disabling the warning 
(either of which should probably be considered only after determining that a 
block or protocol solution is undesirable).

Given what you've provided here, I would be partial to a block solution for 
this. Assuming that your -replaceIn:::: method does something complex between 
the read & write, you could rewrite the main loop to do something like this:

[self setValue: ^(id value) { [aTable setTitle:value]; } fromTable: tableName 
withKey: ^ { return [aTable title]; }];

Note there is no need to pass in 'aTable' now because the blocks capture it 
instead, which can also provide you with additional flexibility to use this 
method elsewhere.
--
David Duncan

_______________________________________________

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