swift [unowned self] 和 [weak self]區別 ObjC weak和 assign區別

weak 一般我們用來修飾delegate ,block中使用 __weak typeof(self) weakSelf = self;  這兩者都是爲了避免產生循環引用

循環引用的產生(如):

@class Dog;
@interface Person : NSObject
///人有一條寵物狗
@property (nonatomic,strong) Dog *dog;

@end


@interface Dog : NSObject
///狗有一個主人   strong換成weak就可以了
@property (nonatomic,strong) Person *person;
@end

Person *p = [[Person alloc] init];
Dog *dog = [[Dog alloc] init];
p.dog = dog;

dog.person = p;

這個地方,如果都用strong修飾,當銷燬person這個對象的時候,會發現dog對象有一個強引用指向person,那麼person就無法銷燬,當銷燬dog對象時,會發現person對其有強引用,這樣一來就會循環引用。代理weak修飾道理就是如此

ios 對象在銷燬之前,調用dealloc之前,會將自己維持的一個weak表(解釋)進行遍歷,所有的weak對象置爲nil ,那麼就得出結論,weak修飾的對象在銷燬時,系統會自動幫我們置爲nil

那麼面試題:

- (void)dealloc
{
    __weak __typeof(self) weakSelf = self;
    NSLog(@"%@",weakSelf);
    
}

答案就是   崩潰了!


assign:一般我們用來修飾基本數據類型,那可以用來修飾對象嗎?可以修飾,但是assign修飾的對象,在銷燬時,不會將此對象置爲nil.那麼程序中如果存在,對象銷燬之後,還可能會調用方法之類的,就會造成野指針


swift中[unowned self]和[weak self] 的區別:

[unowned self] : 在閉包中經常使用來解決循環引用的問題。 當我們確定兩個對象屬於相互引用的情況,而且二者需要銷燬的時機是一樣的,那麼就可以用    例如:viewController 對tableView強引用,tableView強擁有tableViewCell,而二者是需要在 vc銷燬的時候,同時銷燬的,那麼cell裏面的點擊事件通過閉包傳到vc時就可以用[unowned self]  

[weak self] : 也可以用來解決循環引用,其他的作用,以我目前的知識還沒有意識到。 [ weak self] 時self 可能是爲nil的,最常見的crash是,當我們在一個下拉刷新請求數據時,再網絡請求還沒有完成時,就立刻退出當前頁面,那麼vc就被銷燬了,網絡請求完成的閉包再用self就會造成crash

使用 [weak self] 可能會碰到這種寫法

guard let `self` = self else {
      return
}

這裏的 `self` 是與系統self衝突時,可以這麼寫。。你也可以不用self ,做一個強制解包的判斷是否爲空。

另外推薦一個自己寫的彈出自定義視圖的工具,支持pod 給個Star吧!感謝


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章