init方法中模板写法的缘由

可能对于刚接触的Objective-C以及Cocoa编程的同学来说,init方法是很容易造成误解的一个知识点。

这里根据我所阅读到的资料将此问题整体出来,与大家共勉。

if ( ( self = [super init] ) != nil ) {    
}

这是Apple官方推荐的Objective-C中类的init方法的标准写法。但随之而来的问题就是为什么这么写?Objective-C中为什么有异于C++或Java这种典型OOP语言的奇怪写法?

以上问题其实可以归纳为以下几个问题:

  1. 为啥要在子类的初始化方法中主动去调用父类的初始化方法?
  2. 为啥要将父类初始化方法的返回值赋给self?self在super init方法返回之前没有有效值么?
  3. 为啥要对self进行空值判断?

要解释以上几个问题就需要深入了解一下Objective-C编译器在我们看到的表面代码背后都做了些啥。套用变形金刚里面的一句话就是“More than meets the eye”。

Objective-C示例代码如下:

SampleClass *obj = [[SampleClass alloc] initWithString : @ "Sample"];


编译器将代码做如下处理:

class sampleClass = objc_getClass("SampleClass");
SEL allocSelector = @selector(alloc);
SampleClass *obj1 = objc_msgSend(sampleClass, allocSelector);

  SEL initSelector = @selector("initWithString");
  SampleClass *obj2 = objc_msgSend(obj, allocSelector, @"Sample");


不过编译器实际会采用比示例中效率更高的方式来获得class对象以及SEL的值。
如果观察其产生的汇编代码来说,每次的方法调用都会相应的去调用objc_msgSend。

 

那么self究竟是个什么东东?在每个方法调用的时候实际上都暗传了两个隐藏参数self和_cmd。
例如以下Objective-C示例代码:

- (id) initWithString : (NSString) str;

编译器会将方法处理为如下的方式:

id initWithString(id self, SEL _cmd, NSString *str);

self仅仅就是传入每个方法的隐藏参数。方法中会获取或修改self指针中的内容。_cmd参数不是特别常用。

实际上也可以将传统的Objective-C代码用编译器处理后的方式直接写出。

例如将

[obj callWithParameter : param];

改写为

SEL methodSelector = @selector(callWithParameter:);
IMP implementation = class_getMethodImplementation([obj class], methodSelector);
implementation(obj, methodSelector, param);

在implementation函数中self拥有有效值就是因为obj是作为函数的第一个参数传入的。
如果传入其它obj指针,那么self值也会随之改变。
如果这时你往这个函数中传入一个其它类的指针的话,很有程序就会挂点了。

那么"self"参数的作用是什么呢?
方法需要知道它所要处理数据的出处,self参数高速方法这些数据的所在之处。这点也是OOP编程方法的根本。
编译器会使用self参数来解决方法内部对实例变量的引用问题:
例如:

@interface MyClass : NSObject {
NSInteger v;
}
- (void) setValue : (NSInteger) value;
@end

- (void) setValue : (NSInteger) value {
v = value;
}

上面代码会被处理为:

void setValue(id self, SEL _cmd, NSInteger value) {
self->v = value;
}

所以说虽然没有显式写出self,但实际上还是通过self指针才实现对实例变量的访问。

(未完)





 

转载于:https://www.cnblogs.com/scouser/archive/2012/01/09/2317615.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值