使用自我课堂方法 [英] Using self in class method

查看:83
本文介绍了使用自我课堂方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ShareKit中遇到了这段代码,但我不理解作者在类方法中使用 self 的想法。有一个警告:不兼容的指针类型会将 Class发送到参数类型 id< FBSessionDelegate> 我想清除这些警告,以便以后可以看到可能会造成伤害的警告。我能/应该做些什么不会破坏这个?

I came across this code in ShareKit, and I don't understand what the writer had in mind, using self in a class method. There is a warning: Incompatible pointer types sending 'Class' to parameter type id<FBSessionDelegate>. I want to clean up these warnings, so I can see the ones that may hurt later. What can/should I do that won't break this?

这是文件SHKFacebook.m,类名是SHKFacebook

This is is the file SHKFacebook.m and the class name is SHKFacebook

+ (void)logout
{
    FBSession *fbSession; 

    if(!SHKFacebookUseSessionProxy){
        fbSession = [FBSession sessionForApplication:SHKFacebookKey
                                                 secret:SHKFacebookSecret
                                               delegate:self];

    }else {
        fbSession = [FBSession sessionForApplication:SHKFacebookKey
                                        getSessionProxy:SHKFacebookSessionProxyURL
                                               delegate:self];
    }

    [fbSession logout];
}


推荐答案

self 可以在类方法中用作多态Class实例。

self may be used in a class method as a polymorphic Class instance.

因此,类方法 new 可以这样实现:

therefore, the class method new can be implemented like this:

+ (id)new
{
  return [[self alloc] init];
}

并会为所发送的Class实例返回正确的类型:

and would return the correct type for the Class instance that is messaged:

ex a:

NSArray * a = [NSArray new]; // << a is an NSArray

ex b:

NSMutableArray * a = [NSMutableArray new]; // << a is an NSMutableArray

请参见以下说明。

所以您真正要面对的是确保协议中只有实例方法,并且(类)self的方法可以映射为在协议中采用实例方法。

So what you are really faced with is ensuring there are only instance methods in the protocol, and that (Class) self's methods map out to adopt the instance methods in the protocol.

就设计而言……好吧,让我们说我不会这样写。单身人士本来会更清楚,更正确,但我什至不喜欢单身人士,因此我不会走那条路线。

As far as the design... well, let's just say I would not have written it this way. A singleton would have been clearer and more correct, but I don't even like singletons so I would not have taken that route.

产生警告是因为 Class 实例(传递的实例)确实采用了 delegate 参数指定的 @protocol Class 实例不是该类的实例。协议声明确实适用于该类的 instances 。例如,如果您采用 NSLocking ,编译器是否希望您也为协议中声明的每个实例方法实现类方法?答:从不。您正在处理的实现是IMO之一,在这种情况下它会滥用该语言,但它确实起作用。

The warning is produced because the Class instance (what is passed) does adopt the @protocol specified by the delegate parameter. The Class instance is not an instance of the class. A protocol declaration really applies to instances of the class. For example, if you adopt NSLocking, does the compiler expect you to also implement class methods for every instance method declared in the protocol? Answer: Never. The implementation you're dealing with is IMO one of those cases where it's a misuse of the language, but it happens to work.

要澄清术语,

Class 实例是 self 在类方法中:

The "Class instance" is self in a class method:

+ (void)foo { self; }

阶级的实例是自己在实例方法中:

An "instance of the class" is self in an instance method:

- (void)foo { self; }

在实践中,-[NSObjectconformsToProtocol:] + [NSObjectconformsToProtocol:] + [NSObject class] 仅返回 self 所以执行时没有错误。

In practice, -[NSObject conformsToProtocol:] is +[NSObject conformsToProtocol:] and +[NSObject class] just returns self so there are no errors at execution.


我仍然不清楚,为什么我会收到如果代码符合您描述的条件,则会发出警告。

I'm still not clear, then, why I am receiving a warning, if the code meets the criteria you described.

我描述的条件适用于执行 ,但它偏离了语言的语义-因此,编译器对此是绝对正确的。

The criteria I described applies to the execution, but it deviates from the semantics of the language -- thus, the compiler is absolutely correct on this.

要解决该问题:无法告诉编译器我的Class实例符合 protocol ,因为采用声明适用于该类的实例

For a resolution to the problem: There's no way to tell the compiler "My Class instance conforms to protocol" because declaration of adoption applies to instances of the class.

您有两个主要选项:


  1. 干净,正确的方法:使用该类的实例并按定义实现协议。

  1. The clean, correct approach: Use an instance of the class and implement the protocol as defined.

或将类实例转换为协议类型:

or Typecast the class instance to the protocol:

id代表=(id)自我;
fbSession = [FBSession sessionForApplication:SHKFacebookKey
getSessionProxy:SHKFacebookSessionProxyURL
委托人:代表];

id delegate = (id)self; fbSession = [FBSession sessionForApplication:SHKFacebookKey getSessionProxy:SHKFacebookSessionProxyURL delegate:delegate];

如果选择#2,则可能有助于定义协议的实例方法以使用类方法,例如:

If you choose #2, it may help to define the instance methods of the protocol to use class methods, like so:

+ (void)protocolMethod { /* do stuff */ }
- (void)protocolMethod { [self.class protocolMethod]; }

这也意味着您永远不需要实例。这将有所帮助,因为如果协议将更改,它将添加警告。遵循约定时,这些警告会冒泡到类方法上。

that would also imply you never need instances. It would help because it will add warnings if the protocol will change. These warnings would bubble up to class methods when you follow the convention.

为减少噪音,您还可以考虑创建一些方法以将类型转换减少到一个位置:

To reduce noise, you may also consider creating some method to reduce the typecast to one location:

+ (id<SomeProtocol>)sharedSomeProtocolDelegate
{
  return (id<SomeProtocol>)self;
}

- (id<SomeProtocol>)sharedSomeProtocolDelegate
{
  return [[self class] sharedSomeProtocolDelegate];
}

然后您可以这样写:

fbSession = [FBSession sessionForApplication:SHKFacebookKey
                             getSessionProxy:SHKFacebookSessionProxyURL
                                    delegate:[self sharedSomeProtocolDelegate]];

(请注意,这些类型的实现实际上是类集群,您会看到一些

这篇关于使用自我课堂方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆