What is the use of unsafe_unretained attribute?

后端 未结 3 1040
忘了有多久
忘了有多久 2021-02-05 18:31

I know the definition of unsafe_unretained.

So i don\'t expect anyone to write its definition.

I want to know its use with example, and how it wor

3条回答
  •  逝去的感伤
    2021-02-05 18:59

    Here is a specific use case for unsafe_unretained. Say two classes reference each other, one direction being strong and the other direction weak. During dealloc of the first class the weak reference to it from the second class will already be nil, preventing proper cleanup to take place. Replacing the weak reference with an unsafe_unretained reference will solve this issue. See the code sample below:

    @class Foo;
    
    @interface Bar: NSObject
    
    //Replacing weak with unsafe_unretained prevents this property from becoming nil during Foo.dealloc
    @property (nonatomic, weak) Foo *foo;
    
    - (id)initWithFoo:(Foo *)foo;
    
    @end
    
    @interface Foo : NSObject
    
    @property (nonatomic, strong) Bar *bar;
    
    - (void)startObserving;
    - (void)endObserving;
    
    @end
    
    @implementation Bar
    
    - (id)initWithFoo:(Foo *)foo {
        if ((self = [super init])) {
            self.foo = foo;
    
            //Start observing
            [self.foo startObserving];
        }
        return self;
    }
    
    - (void)dealloc {
        //Since foo is a weak property, self.foo may actually be nil at this point! See dealloc of class Foo.
        [self.foo endObserving];
    }
    
    @end
    
    @implementation Foo
    
    - (id)init {
        if ((self = [super init])) {
            self.bar = [[Bar alloc] initWithFoo:self];
        }
        return self;
    }
    
    - (void)dealloc {
        //This will trigger the deallocation of bar. However, at this point all weak references to self will return nil already!
        self.bar = nil;
    
        //endObserving is never called, because Bar.foo reference was already nil.
    }
    
    - (void)startObserving {
        NSLog(@"Start observing");
    }
    
    - (void)endObserving {
        NSLog(@"End observing");
    }
    
    @end
    

提交回复
热议问题