self can be used in a class method as an instance of a polymorphic class.
therefore, the method of the new class can be implemented as follows:
+ (id)new { return [[self alloc] init]; }
and will return the correct type for the class instance that is sent to the message:
ex a:
NSArray * a = [NSArray new];
ex b:
NSMutableArray * a = [NSMutableArray new];
see note below.
So, in fact, you are faced with the fact that in the protocol there are only instance methods, and that (self) methods of the class (Class) to accept the instance methods in the protocol.
As for the design ... well, let's put it this way, I would not write it like that. Singleton would be clearer and more correct, but I don’t even like loners, so I would not go this way.
A warning is generated because the class instance (what is being passed) takes the @protocol value specified by the delegate parameter. An instance of Class not an instance of a class. The protocol declaration does apply to class instances. For example, if you accept NSLocking , NSLocking compiler expect that you will also apply class methods for each instance method declared in the protocol? Answer: Never. The implementation you are dealing with is IMO, one of those cases where it is misuse of the language, but it works.
To clarify the terminology:
" Class instance" self in the class method:
+ (void)foo { self; }
The "class instance" is self in the instance method:
- (void)foo { self; }
In practice -[NSObject conformsToProtocol:] +[NSObject conformsToProtocol:] and +[NSObject class] just returns self , so there are no errors when executing.
It’s still not clear to me why I get a warning if the code meets the criteria you specified.
The criteria that I described relate to execution, but it differs from the semantics of the language - thus, the compiler is absolutely right to do so.
To solve the problem: there is no way to tell the compiler "an instance of My Class conforms to the protocol", because the declaration of acceptance applies to instances of the class.
You have two main options:
A clean, correct approach: use an instance of the class and implement the protocol as defined.
or Typecast class instance for the protocol:
id delegate = (id) self; fbSession = [FBSession sessionForApplication: SHKFacebookKey getSessionProxy: SHKFacebookSessionProxyURL Delegate: delegate];
If you select # 2, this can help determine the protocol instance methods for using class methods, for example:
+ (void)protocolMethod { } - (void)protocolMethod { [self.class protocolMethod]; }
which also implies that you never need instances. This will help because it will add warnings if the protocol changes. These warnings will resort to class methods when you follow this convention.
To reduce noise, you can also consider creating some method to reduce typecasting to a single location:
+ (id<SomeProtocol>)sharedSomeProtocolDelegate { return (id<SomeProtocol>)self; } - (id<SomeProtocol>)sharedSomeProtocolDelegate { return [[self class] sharedSomeProtocolDelegate]; }
then you can simply write:
fbSession = [FBSession sessionForApplication:SHKFacebookKey getSessionProxy:SHKFacebookSessionProxyURL delegate:[self sharedSomeProtocolDelegate]];
(note that implementations of these types are actually class clusters, and you will see something else in the debugger or printed)