1

Below is a simple PerformSelector that sends a message to obj to perform the looping method. All works well but I get the following yellow warning.

PerformSelector may cause a leak because its selector is unknown.

#import "MyClass.h"
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyClass *obj = [[MyClass alloc]init];

        SEL mySel = @selector(looping);
        [obj performSelector:mySel];
    }
    return 0;
}

This warning does not make sense because the performSelector must be aware of mySel because the looping method does get called - any ideas whats going on ??


Update

MyClass.h

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

-(void)looping;

@end

MyClass.m

#import "MyClass.h"

@implementation MyClass

-(void)looping{

    NSLog(@"Hey, i'm looping");

}

@end
justin
  • 101,751
  • 13
  • 172
  • 222
pete
  • 2,750
  • 4
  • 20
  • 30

2 Answers2

2

Update -- The Real Answer

This is ARC specific:

performSelector may cause a leak because its selector is unknown

In short, ARC uses information based on the naming conventions and any additional attributes bound to the selector. When accessing a selector by name and performing it via the performSelector: family of methods, that information is lost and the compiler is warning you that it must make some assumptions regarding reference counting because this information is stripped away.

In short, the specific program you posted is safe but you are encouraged to use an alternative which is ARC-friendly.

The Previous Response

A selector's declaration does not need to be visible to the current translation in order to call it.

The compiler is allowed to assume default types for parameters and return types for class and instance methods (id is the default).

There are several compiler warnings which can warn you of these shady actions.

You probably forgot to declare the selector looping in the @interface, or you may have omitted the colon, if it has arguments: looping: would be its name.

Community
  • 1
  • 1
justin
  • 101,751
  • 13
  • 172
  • 222
  • Thanks for you help but as a newb Im still bit confused.If possible could you explain or even better send an example of what you mean by not declaring the current translation. The looping method is in the interface and does not require a colon because it does not take in any arguments (it simply logs out a string). – pete May 10 '12 at 09:46
  • @pete thanks for expanding your post. i've updated it with a real answer. – justin May 10 '12 at 10:03
  • that explains it and yes I have got ARC switched on. Thanks – pete May 10 '12 at 10:19
0

this warning is due to that u have not told the compiler where the selector resides, import the file where it is or add the selector to header file where it should be

Saad
  • 8,501
  • 2
  • 36
  • 49
  • the selector is a class method from MyClass. I have placed #import "MyClass.h" at the top of main - – pete May 10 '12 at 09:40
  • do u have declared that in ur MyClass.h? – Saad May 10 '12 at 09:40
  • compiler only knows the things that are predeclared to a line or included through some library – Saad May 10 '12 at 09:41
  • yes the method is declared in the header file - I have just made an edit to show all files – pete May 10 '12 at 09:52
  • ok do this then if([obj respondsToselecto:mySel]){[obj performSelector:mySel];} – Saad May 10 '12 at 09:57
  • I had to change your you code to: if([obj respondsToSelector:mySel]) { [obj performSelector:mySel];}; But all this does is call the method again. As stated - the selector works but I get a warning – pete May 10 '12 at 10:10