天天看點

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(這裡不僅僅是像self發送消息,因為像nil發送消息不會造成崩潰)就會造成crash

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

guard let `self` = self else {
      return
}           

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

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