返回

深入浅出iOS内存管理——weak原理剖析

IOS

weak原理探究
weak是iOS的一个修饰符,修饰的变量具备如下特征:

  • 不会对引用对象进行reatain(即引用计数+1)
  • 对象释放时weak会自动置为nil
  • 调用方法不会崩溃

weak经常被用在ARC的环境中来代替assign修饰符,从语义上更容易理解变量的所有权。

weak的底层实现原理

weak修饰符的实现原理:

weak修饰符的底层实现原理是通过使用unsafe_unretained修饰符来实现的。unsafe_unretained修饰符的作用是告诉编译器不要对变量进行引用计数,从而避免对变量进行reatainrelease操作。当对象释放时,unsafe_unretained修饰符会自动将变量置为nil,从而避免对对象进行无效的调用。

weak修饰符的使用场景:

weak修饰符经常被用在以下场景中:

  • 当变量只被用作方法参数时
  • 当变量只被用作闭包变量时
  • 当变量只被用作临时变量时

weak与assign修饰符的区别

weak修饰符与assign修饰符的主要区别在于:

  • weak修饰符不会对引用对象进行reatain操作,而assign修饰符会
  • weak修饰符在对象释放时会自动置为nil,而assign修饰符不会

weak的应用举例

示例一:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    __weak typeof(self) weakSelf = self;
    
    // Do something asynchronously
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Use weakSelf to access the view controller
        [weakSelf doSomething];
    });
}

在这个示例中,weakSelf是一个weak修饰符修饰的变量,它引用了self变量。当self变量被释放时,weakSelf会自动置为nil,从而避免对self变量进行无效的调用。

示例二:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndex:(NSInteger)index {
    __weak typeof(self) weakSelf = self;
    
    // Do something asynchronously
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Use weakSelf to access the view controller
        [weakSelf didSelectRowAtIndex:index];
    });
}

在这个示例中,weakSelf是一个weak修饰符修饰的变量,它引用了self变量。当self变量被释放时,weakSelf会自动置为nil,从而避免对self变量进行无效的调用。

结语

weak修饰符是一个非常有用的工具,它可以帮助我们避免内存泄漏和崩溃。在ARC的环境中,weak修饰符经常被用作assign修饰符的替代品,从语义上更容易理解变量的所有权。希望这篇文章对您有所帮助,如果您有任何问题,请随时与我联系。