类方法中使用self会是什么结果,下午在编码中遇到这个问题:“在类方法中直接使用了self,导致函数没有被调用。”然后,顺便研究了一下,在类(或实例)方法中self是如何表现的。
第一、在类方法中使用self作为参数,需要特别注意。
第二、在类(或实例)方法中使用self调用方法(如果是错误的使用,编译器会给出编译错误)。
第一种情况:在类方法中使用self作为参数
一般来说:当参数指定类型,程序员传入的self也是对应类型。但是,编译器给出警告。
编译器提示开发者:把Class当做TabBarController使用了
另外一种情况:如果参数是id类型,那么编译器不报错。如下代码:
+ (void)goToInfoPage{
RequestItem *requestItem = [[RequestItem alloc] initWithOwner:[TabBarController sharedInstance]];/*使用self可以编译,但达不到预期效果*/
[requestItem setDelegateTarget:[TabBarController sharedController] /*使用self可以编译,但达不到预期效果*/ succeedMethod:@selector(requestInfoSuccess:) failedMethod:@selector(requestInfoFailure:)];
}
其中 initWithOwner和setDelegateTarget的参数都是id类型,上面的代码使用self可以通过编译,但在request后,requestInfoSuccess和requestInfoFailure一个都没有被执行。在initWithOwner函数中打印参数的值如下:
————使用self————
(lldb) po delegate
TabBarController
————使用[TabBarController sharedInstance]————
(lldb) po delegate
<TabBarController: 0x18952020>
很明显:使用self,实际上是Class类型,并不是我们期望的类对象。所以,在RequestItem里面判断response selector的时候就没有判断出来。
针对第二种场景:在类(实例)方法中使用self调用方法
1. 实例方法中,self【可以】调用实例方法(最常见)
2. 实例方法中,self【不可以】调用类方法,此时self不是Class。【编译错误】No visible @interface for 'xx' declares the selector ‘xx’
3. 类方法中,self【可以】调用类方法,此时self是Class
4. 类方法中,self【不可以】调用实例方法。【编译错误】 No known class method for selector ‘xxxxx’
self跟着函数的本质不同,也会不同。所以,在类方法中使用self,就要特别注意了。
【总结】:
1,实例方法里面的self,是对象的首地址。
2,类方法里面的self,是Class。类方法不可以使用实例变量,但可以使用self,因为self不是实例变量。此时.self是Class
尽管在同一个类里面的使用self,但是self却有着不同的解读。在类方法里面的self,可以翻译成class self;在实例方法里面的self,应该被翻译成为object self。在类方法里面的self和实例方法里面的self有着本质上的不同,尽管他们的名字都叫self。