简体   繁体   中英

Weak self vs self when using closure defined in swift in objective c

Let say :- I have a ViewController created in objeticve - c ( Number.m ). I have a TableViewCell created in swift which contains button ( CalculateSum.swift )

Now i need to tell VC that button has been tapped and send tag of the button. For this i use closure.

Swift :-

var calculateSumBtnTapped: ((UITableViewCell) -> Void)?

@IBAction func calculateSumBtnDidTapped(_ sender: Any) {
        self.calculateSumBtnTapped?(self)
}

Now as we see CalculateSum.swift holds strong reference to calculateSumBtnTapped property.

Now i call this closure as block in Number.m

CalculateSum * calculateSum = [tableView dequeueReusableCellWithIdentifier:@"sum" forIndexPath:indexPath];
__block typeof(self) weakSelf = self;
calculateSum.calculateSumBtnTapped = ^(UITableViewCell * _Nonnull calculateSumCell) {
            // calculating sum by tag
      weakSelf.sum = weakSelf.sum + calculateSumCell.tag
};

Is it necessary to use self as weakself ? or I can use self as it is ?

First of all try to understand what is a retaincycle and how it will affect your application..

A retain cycle is a condition that happens when two objects keeps strong reference to each others.

在此处输入图片说明

In such cases these objects won't get deallocated and it will stay in memory forever and leads to memory leak.

Retain cycle in blocks and why should we use weakself

Closures and blocks are independent memory objects and they will retain the objects they reference so if we are accessing any class variable or method inside the closure or block using self then there is a chance for retain cycle

self.myBlock = ^{ self.someProperty = xyz; }; // RETAIN CYCLE

will get this warning

Capturing 'self' strongly in this block is likely to lead to a retain cycle

To avoid such situation we should weakSelf to access members

__weak typeof(self) weakSelf = self;

`self.myBlock = ^{ weakSelf.someProperty = xyz; };`

So there is a rule like always use weakSelf in blocks but there are some special cases like animation blocks

[UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded]; }];

Here we can use self inside the block because the blocks get destroyed automatically once animation completed.

When an object A reference another object B strongly and object B references object A strongly, ARC cant dealloc there two objects thus creating retain cycle which may increase the memory footprint of your app and may cause app to crash. To avoid retain cycle one of the reference should be weak. Thats why you need to use weakSelf inside the block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM