gpt4 book ai didi

objective-c - 在类方法中使用 self

转载 作者:太空狗 更新时间:2023-10-30 03:28:31 26 4
gpt4 key购买 nike

我在 ShareKit 中看到这段代码,我不明白作者的想法,使用 self在类方法中。出现警告:不兼容的指针类型将“类”发送到参数类型 id<FBSessionDelegate> . 我想清理这些警告,这样我以后就可以看到那些可能会造成伤害的警告。我可以/应该做什么才不会破坏它?

这是文件SHKFacebook.m,类名是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 可以在类方法中用作多态类实例。

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

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

并且会为被消息传递的 Class 实例返回正确的类型:

例如:

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

例如:

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

请参阅下面的注释。

因此,您真正面临的是确保协议(protocol)中只有实例方法,并且(类)self 的方法映射为采用协议(protocol)中的实例方法。

就设计而言……好吧,我不会这样写的。单例会更清晰、更正确,但我什至不喜欢单例,所以我不会走那条路。

产生警告是因为 Class 实例(传递的内容)确实采用了 delegate 参数指定的 @protocolClass 实例不是该类的实例。协议(protocol)声明真正适用于该类的实例。例如,如果你采用了NSLocking,编译器是否期望你也为协议(protocol)中声明的每个实例方法实现类方法?答:从不。您正在处理的实现是 IMO 中的一种情况,它是对语言的滥用,但它恰好有效。

澄清术语:

Class 实例”是类方法中的self:

+ (void)foo { self; }

“类的实例”是实例方法中的self:

- (void)foo { self; }

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

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

我描述的标准适用于执行,但它偏离了语言的语义——因此,编译器在这方面是绝对正确的。

对于问题的解决方案:无法告诉编译器“我的类实例符合协议(protocol)”,因为采用声明适用于类的实例

您有两个主要选择:

  1. 简洁、正确的方法:使用类的实例并按定义实现协议(protocol)。

  2. 或将类实例类型转换为协议(protocol):

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

如果您选择#2,它可能有助于定义协议(protocol)的实例方法以使用类方法,如下所示:

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

这也意味着您永远不需要实例。这会有所帮助,因为如果协议(protocol)发生变化,它会添加警告。当您遵循约定时,这些警告会冒泡到类方法中。

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

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

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

然后你可以写:

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

(请注意,这些类型的实现实际上是类簇,您会在调试器或打印中看到不同的东西)

关于objective-c - 在类方法中使用 self,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9028549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com