iOS 方法中参数的引用类型

最近用了一个三方库,线上crash收集日志经常会收集到crash。报的是野指针,所以看不到堆栈信息,通过排查对比新增代码,渐渐锁定问题出现在下面这个函数:

- (void)removeFromSuperview {
    [super removeFromSuperview];
    self.completionBlock = nil;
    [self _removeCurrentAnimationIfNecessary];
}

通过查询资料,得知一个普通的参数,在进入这个函数的时候,会被strong一次,也就是强引用一次,所以我们不用担心在方法执行到一半的时候,参数被释放的问题。

我们知道OC中的消息机制,调用方法实际上最终最终调用的是objc_msgSend(id self, SEL op, ...),从这里我们也可以看出,实际上我们的参数还有2个隐形的,一个是self,一个是对应的SEL。这里我们不讨论SEL

ARC下,一般的参数都是如我上面所说,是会被strong的,但是self这个参数比较特殊,是__unsafe_unretained引用的,也就是单纯的指针赋值,不改变引用计数,也不会在释放的时候被置为nil

如上面的例子,如果这个view没有在外部被强引用,执行removeFromSuperview方法,当程序到[super removeFromSuperview]这行代码之后,这个view会立马被dealloc,然而因为self这个参数没有被置为nil,所以也就造成了后面调用到self时报野指针的crash。应该修改为下面的写法。

- (void)removeFromSuperview {
    self.completionBlock = nil;
    [self _removeCurrentAnimationIfNecessary];
    [super removeFromSuperview];
}

你可能感兴趣的:(iOS 方法中参数的引用类型)