• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Arc and performSelector
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Arc and performSelector


  • Subject: Re: Arc and performSelector
  • From: David Duncan <email@hidden>
  • Date: Mon, 17 Oct 2011 10:05:37 -0700

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 (email@hidden)

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:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Arc and performSelector
      • From: "Gerriet M. Denkmann" <email@hidden>
References: 
 >Arc and performSelector (From: "Gerriet M. Denkmann" <email@hidden>)

  • Prev by Date: Re: Arcs and Bridges
  • Next by Date: Re: Use storyboard in iOS app
  • Previous by thread: Arc and performSelector
  • Next by thread: Re: Arc and performSelector
  • Index(es):
    • Date
    • Thread