欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > 内容正文

类方法中使用self注意事项,类方法self注意事项

来源: 开发者 投稿于  被查看 49583 次 评论:41

类方法中使用self注意事项,类方法self注意事项


        类方法中使用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。
相关频道:

用户评论