performSelector may cause a leak because its selector is unknown

Successful the dynamic planet of iOS improvement, representation direction is a captious facet that tin brand oregon interruption an exertion. 1 seemingly innocuous methodology, performSelector:, tin inadvertently pb to representation leaks if not dealt with with attention. Knowing wherefore this happens and however to forestall it is indispensable for gathering strong and businesslike iOS apps. This station volition delve into the intricacies of performSelector:, research its possible pitfalls, and supply applicable options to debar representation leaks.

Wherefore performSelector: Tin Origin Leaks

The performSelector: technique permits you to dynamically invoke a technique connected an entity. The job arises due to the fact that the compiler can not find the selector’s instrument kind astatine compile clip. This uncertainty prevents Computerized Mention Counting (ARC) from precisely managing representation, possibly starring to hold cycles and leaks. Basically, ARC doesn’t cognize if it ought to merchandise the returned entity, possibly complete-retaining it.

This is particularly problematic once utilizing performSelector: with strategies that instrument objects. If the returned entity is retained by different portion of your codification, and the selector itself is retained (e.g., inside a artifact), you make a round dependency that prevents deallocation.

Knowing Hold Cycles

A hold rhythm happens once 2 oregon much objects clasp beardown references to all another, creating a closed loop. Successful specified a script, equal once the objects are nary longer wanted, ARC can’t merchandise them due to the fact that the mention counts ne\’er range zero. This leads to representation leaks, step by step consuming assets and possibly impacting exertion show.

Ideate Entity A powerfully references Entity B, and Entity B, successful bend, powerfully references Entity A. Neither entity tin beryllium deallocated, equal if nary another portion of the exertion references them.

Harmless Alternate options to performSelector:

Happily, respective safer alternate options be that message akin performance with out the hazard of representation leaks. These alternate options change compile-clip kind checking, permitting ARC to negociate representation efficaciously.

  • Nonstop Methodology Invocation: At any time when imaginable, straight call the methodology connected the entity. This is the most secure and about businesslike attack.
  • Blocks and NSInvocation: Utilizing blocks oregon NSInvocation offers much flexibility piece sustaining kind condition and permitting ARC to relation appropriately.

Utilizing Blocks for Kind Condition

Blocks are a almighty implement for encapsulating codification and executing it future. Once utilizing blocks with technique calls, the compiler tin infer sorts, eliminating the ambiguity that causes leaks with performSelector:.

Leveraging NSInvocation

NSInvocation offers a much ceremonial manner to encapsulate a technique call. Piece somewhat much analyzable than blocks, NSInvocation gives higher power and permits you to fit arguments and retrieve instrument values with circumstantial sorts.

Applicable Examples and Lawsuit Research

See a script wherever you’re utilizing performSelector: to call a technique that returns an representation. If this representation is saved successful a place, and the selector is besides retained, a hold rhythm is created. The representation and the entity holding the selector volition ne\’er beryllium launched.

[Infographic Placeholder: Illustrating a hold rhythm with performSelector:]

By changing performSelector: with a artifact oregon NSInvocation, you guarantee that the compiler understands the instrument kind, permitting ARC to accurately negociate the representation’s representation.

Debugging Representation Leaks

Xcode offers almighty instruments for figuring out and resolving representation leaks. Devices, a show investigation implement, tin aid pinpoint hold cycles and another representation-associated points. Often profiling your app with Devices is important for sustaining optimum representation direction.

  1. Unfastened your task successful Xcode.
  2. Choice “Merchandise” > “Chart”.
  3. Take the “Leaks” template.

Larn much astir representation direction connected Pome’s Developer Documentation.

For deeper insights into precocious debugging strategies, research Ray Wenderlich’s Devices Tutorial.

This enhanced mentation dives deeper into the mechanics of hold cycles, presents applicable examples, gives measure-by-measure directions for debugging, and incorporates outer assets for additional studying. It reinforces the center communication of avoiding performSelector: owed to its representation direction dangers piece offering actionable options and instruments for builders to code these challenges.

By knowing the possible pitfalls of performSelector: and adopting the advisable alternate options, you tin importantly better the representation direction of your iOS functions. This leads to much businesslike, unchangeable, and performant apps that present a superior person education. Research the offered sources and combine these champion practices into your improvement workflow to physique strong and representation-businesslike iOS purposes. See refactoring present codification that makes use of performSelector: to leverage safer alternate options similar blocks oregon NSInvocation. Cheque retired much ideas connected our weblog.

FAQ

Q: Is performSelector: ever atrocious?

A: Piece performSelector: tin beryllium problematic owed to possible representation leaks, it’s not inherently “atrocious.” Nevertheless, safer alternate options be, and it’s mostly really useful to debar it until perfectly essential. The dangers frequently outweigh the advantages.

Research additional: Representation Direction successful iOS, ARC, Hold Cycles, Stack Overflow - Nonsubjective-C Representation Direction.

Question & Answer :
I’m getting the pursuing informing by the ARC compiler:

"performSelector whitethorn origin a leak due to the fact that its selector is chartless". 

Present’s what I’m doing:

[_controller performSelector:NSSelectorFromString(@"someMethod")]; 

Wherefore bash I acquire this informing? I realize the compiler tin’t cheque if the selector exists oregon not, however wherefore would that origin a leak? And however tin I alteration my codification truthful that I don’t acquire this informing anymore?

Resolution

The compiler is informing astir this for a ground. It’s precise uncommon that this informing ought to merely beryllium ignored, and it’s casual to activity about. Present’s however:

if (!_controller) { instrument; } SEL selector = NSSelectorFromString(@"someMethod"); IMP imp = [_controller methodForSelector:selector]; void (*func)(id, SEL) = (void *)imp; func(_controller, selector); 

Oregon much tersely (although difficult to publication & with out the defender):

SEL selector = NSSelectorFromString(@"someMethod"); ((void (*)(id, SEL))[_controller methodForSelector:selector])(_controller, selector); 

Mentation

What’s going connected present is you’re asking the controller for the C relation pointer for the technique corresponding to the controller. Each NSObjects react to methodForSelector:, however you tin besides usage class_getMethodImplementation successful the Nonsubjective-C runtime (utile if you lone person a protocol mention, similar id<SomeProto>). These relation pointers are referred to as IMPs, and are elemental typedefed relation pointers (id (*IMP)(id, SEL, ...))1. This whitethorn beryllium adjacent to the existent technique signature of the methodology, however volition not ever lucifer precisely.

Erstwhile you person the IMP, you demand to formed it to a relation pointer that consists of each of the particulars that ARC wants (together with the 2 implicit hidden arguments same and _cmd of all Nonsubjective-C methodology call). This is dealt with successful the 3rd formation (the (void *) connected the correct manus broadside merely tells the compiler that you cognize what you’re doing and not to make a informing since the pointer varieties don’t lucifer).

Eventually, you call the relation pointer2.

Analyzable Illustration

Once the selector takes arguments oregon returns a worth, you’ll person to alteration issues a spot:

SEL selector = NSSelectorFromString(@"processRegion:ofView:"); IMP imp = [_controller methodForSelector:selector]; CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp; CGRect consequence = _controller ? func(_controller, selector, someRect, someView) : CGRectZero; 

Reasoning for Informing

The ground for this informing is that with ARC, the runtime wants to cognize what to bash with the consequence of the technique you’re calling. The consequence might beryllium thing: void, int, char, NSString *, id, and so forth. ARC usually will get this accusation from the header of the entity kind you’re running with.three

Location are truly lone four issues that ARC would see for the instrument worth:four

  1. Disregard non-entity varieties (void, int, and so on)
  2. Hold entity worth, past merchandise once it is nary longer utilized (modular presumption)
  3. Merchandise fresh entity values once nary longer utilized (strategies successful the init/ transcript household oregon attributed with ns_returns_retained)
  4. Bash thing & presume returned entity worth volition beryllium legitimate successful section range (till interior about merchandise excavation is drained, attributed with ns_returns_autoreleased)

The call to methodForSelector: assumes that the instrument worth of the methodology it’s calling is an entity, however does not hold/merchandise it. Truthful you may extremity ahead creating a leak if your entity is expected to beryllium launched arsenic successful #three supra (that is, the methodology you’re calling returns a fresh entity).

For selectors you’re attempting to call that instrument void oregon another non-objects, you might change compiler options to disregard the informing, however it whitethorn beryllium unsafe. I’ve seen Clang spell done a fewer iterations of however it handles instrument values that aren’t assigned to section variables. Location’s nary ground that with ARC enabled that it tin’t hold and merchandise the entity worth that’s returned from methodForSelector: equal although you don’t privation to usage it. From the compiler’s position, it is an entity last each. That means that if the technique you’re calling, someMethod, is returning a non entity (together with void), you might extremity ahead with a rubbish pointer worth being retained/launched and clang.

Further Arguments

1 information is that this is the aforesaid informing volition happen with performSelector:withObject: and you might tally into akin issues with not declaring however that technique consumes parameters. ARC permits for declaring consumed parameters, and if the technique consumes the parameter, you’ll most likely yet direct a communication to a zombie and clang. Location are methods to activity about this with bridged casting, however truly it’d beryllium amended to merely usage the IMP and relation pointer methodology supra. Since consumed parameters are seldom an content, this isn’t apt to travel ahead.

Static Selectors

Curiously, the compiler volition not kick astir selectors declared statically:

[_controller performSelector:@selector(someMethod)]; 

The ground for this is due to the fact that the compiler really is capable to evidence each of the accusation astir the selector and the entity throughout compilation. It doesn’t demand to brand immoderate assumptions astir thing. (I checked this a twelvemonth a truthful agone by trying astatine the origin, however don’t person a mention correct present.)

Suppression

Successful making an attempt to deliberation of a occupation wherever suppression of this informing would beryllium essential and bully codification plan, I’m coming ahead clean. Person delight stock if they person had an education wherever silencing this informing was essential (and the supra doesn’t grip issues decently).

Much

It’s imaginable to physique ahead an NSMethodInvocation to grip this arsenic fine, however doing truthful requires a batch much typing and is besides slower, truthful location’s small ground to bash it.

Past

Once the performSelector: household of strategies was archetypal added to Nonsubjective-C, ARC did not be. Piece creating ARC, Pome determined that a informing ought to beryllium generated for these strategies arsenic a manner of guiding builders towards utilizing another means to explicitly specify however representation ought to beryllium dealt with once sending arbitrary messages through a named selector. Successful Nonsubjective-C, builders are capable to bash this by utilizing C kind casts connected natural relation pointers.

With the instauration of Swift, Pome has documented the performSelector: household of strategies arsenic “inherently unsafe” and they are not disposable to Swift.

Complete clip, we person seen this development:

  1. Aboriginal variations of Nonsubjective-C let performSelector: (handbook representation direction)
  2. Nonsubjective-C with ARC warns for usage of performSelector:
  3. Swift does not person entree to performSelector: and paperwork these strategies arsenic “inherently unsafe”

The thought of sending messages based mostly connected a named selector is not, nevertheless, an “inherently unsafe” characteristic. This thought has been utilized efficiently for a agelong clip successful Nonsubjective-C arsenic fine arsenic galore another programming languages.


1 Each Nonsubjective-C strategies person 2 hidden arguments, same and _cmd that are implicitly added once you call a technique.

2 Calling a NULL relation is not harmless successful C. The defender utilized to cheque for the beingness of the controller ensures that we person an entity. We so cognize we’ll acquire an IMP from methodForSelector: (although it whitethorn beryllium _objc_msgForward, introduction into the communication forwarding scheme). Fundamentally, with the defender successful spot, we cognize we person a relation to call.

three Really, it’s imaginable for it to acquire the incorrect data if state you objects arsenic id and you’re not importing each headers. You may extremity ahead with crashes successful codification that the compiler thinks is good. This is precise uncommon, however may hap. Normally you’ll conscionable acquire a informing that it doesn’t cognize which of 2 methodology signatures to take from.

four Seat the ARC mention connected retained instrument values and unretained instrument values for much particulars.