类方法中使用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。

时间: 2024-10-08 22:15:45

类方法中使用self注意事项的相关文章

接口和类方法中的 SELF

接口和类方法中的 SELF 由 王巍 (@ONEVCAT) 发布于 2015/06/10 我们在看一些接口的定义时,可能会注意到出现了首字母大写的 Self 出现在类型的位置上: protocol IntervalType { //... /// Return `rhs` clamped to `self`. The bounds of the result, even /// if it is empty, are always within the bounds of `self` func

AW笔记本升级SSD,外接双屏中的一些注意事项

自己留一个mark,以后提醒用. 1)机械硬盘状态下利用alien sprawn创建的系统恢复U盘,无法在SSD下使用,因为SSD中没有recovery分区,只能使用随机携带的系统恢复光盘: 2)最好在SSD安装系统之前,先用机械硬盘引导,在windows下使用diskgenious进行格式化分区,4k字节对齐: 3)将SSD安装在硬盘盘位1,因为是最经常使用,并在bios中设置SATA option为ACHI: 4)利用恢复光盘进行系统安装,记住选择SSD的分区: 5)系统安装成功后,按照网上

IOS 中NSTimer使用注意事项

1.初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelec

Storm中Spout使用注意事项小结

Storm中Spout用于读取并向计算拓扑中发送数据源,最近在调试一个topology时遇到了系统qps低,处理速度达不到要求的问题,经过排查后发现是由于对Spout的使用模式不当导致的多线程同步等待.这里罗列几点个人觉得编写Spout代码时需要特别注意的地方: 1. 最常用的模式是使用一个线程安全的queue,如BlockingQueue,spout主线程从queue中读取数据:另外的一个或多个线程负责从数据源(如各种消息中间件.db等)读取数据并放入queue中. 2. 如果不关心数据是否丢

关于myBatis配置中的一些注意事项

最近在学习mybatis,在网上查阅资料,并按照别人的范例来测试,总会出一些错误,这里把配置过程中的一些注意事项梳理一下. 一.导包(用eclipse开发) 1.如果你新建的是普通的project,需要在工程目录下,新建一个文件夹(一般为lib),然后需要手动导包,具体操作是:选中包右键-Build Path-add to Build Path.之前的文件夹不能删除,因为它实际上加载的是这些包的路径. 2.如果你新建的是web工程,只需要把相关包放到WEB-INF/lib 中即可,它会自动导包,

使用MatLab过程中的一些注意事项

1.如果输入单行后直接按回车,如 则直接显示结果如下 2.如果希望输入多行,则需要在行尾使用"Shift"+"Enter"组合键来换行 3.如果输入多行,但只需显示最后一条结果,可以在之前的语句末尾使用";" //未完待续 使用MatLab过程中的一些注意事项

动态生成代码中的事件注意事项

var d = '<a href="#" title="查看"  onclick ="ViewById(' + row.Id + ','+"'"+row.vpdm+"'"+')">' + value + '</a>'; "'"+row.vpdm+"'"这里要加上单引号,前面的row.Id是int所以不用,但后面的是字符串类型就得加上单引号,要不

Android 4.4 中 WebView 使用注意事项

Android 4.4 中 WebView 使用注意事项 自Android 4.4起,Android中的WebView开始基于Chromium( 这大概是因为Android部门负责人从Andy Rubin变成了Chrome部门的主管Sundar Pichai了吧,_). 这个改变,使得WebView的性能大幅度提升,并且对HTML5, CSS3, and JavaScript有了更好的支持. 那么,作为一个客户端开发者,我们写代码的时候需要注意哪些呢? 1.多线程 如果你在子线程中调用WebVi

自学中应该注意的事项

这两天西安天气比较热,心里也浮躁的很,电脑一直吹热风,窗外还有k歌比赛,(那歌声你懂得),一天马上就要过去了,还是想坐下来写点东西.. 继昨天的文章浅析java(多方面解读)之后,今天本来是想写点关于java类型还有操作符的东西,但是想到了那句老话"磨刀不误砍柴工",我想先把自学时应该注意的事项先说说,(自认为学习方法很重要,不知道你怎么看),关于自学,几乎每个人都有自己的一套学习方法,但是有时候自己都没有发现学习方法是错误的,浪费了自己很多的时间. 下面谈一下我的看法: a>作