iOS中__weak和__strong属性有什么区别?

4

这是一个开源项目中的代码:

- (id) initWithContentPath: (NSString *) path parameters: (NSDictionary *) parameters
{
    NSAssert(path.length > 0, @"empty path");
    playPath = path;
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        _moviePosition = 0;
        _startTime = -1;
        self.wantsFullScreenLayout = YES;

        _decodeDuration = DEFAULT_DECODE_DURATION;
        _minBufferedDuration = LOCAL_BUFFERED_DURATION;

        _parameters = parameters;

        __weak KxMovieViewController *weakSelf = self;

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            NSError *error;
            KxMovieDecoder *decoder;
            decoder = [KxMovieDecoder movieDecoderWithContentPath:path error:&error];

            NSLog(@"KxMovie load video %@", path);

            __strong KxMovieViewController *strongSelf = weakSelf;
            if (strongSelf) {

                dispatch_sync(dispatch_get_main_queue(), ^{

                    [strongSelf setMovieDecoder:decoder withError:error];                    
                });
            }
        });
    }
    return self;
}

我想知道一个类什么情况下需要将self设置为strongweak


2
我认为那段代码实际上并没有做对。由于没有保留该块,因此不需要使用“weakSelf”。 - Carl Veazey
@CarlVeazey 这个项目在 https://github.com/kolyvan/kxmovie ,它运行良好,但是当将代码复制(合并)到其他项目时无法工作。 - why
4
理解 Objective-C 中的强引用和弱引用是非常重要的概念,通常在任何课程/书籍中都会很早就涉及到。如果你问的问题是关于代码的(“我理解了强引用和弱引用,但我不知道它在这段代码中如何使用”),请重新表述清楚。如果你想要一般的理解,我建议阅读 Objective-C 参考资料,因为它将对你未来的所有代码都至关重要。此外,这个问题已经在这里得到回答:https://dev59.com/uWox5IYBdhLWcg3wWjDQ - David Ravetti
2个回答

5
强引用在你还在使用对象的时候,可以确保该对象不会被释放。而弱引用则表示你不关心所引用的对象是否被释放。当没有强引用指向某个对象时,所有弱引用都会被自动设置为nil
通俗易懂地说,只要有至少一个强引用指向一个对象,该对象就不会被释放。当没有强引用指向该对象时,所有弱引用(如果有的话)都会被设置为nil

1
+1,但有一个警告:如果您在iOS 4.x或OS X 10.6上使用ARC,则弱引用不会被设置为nil。在这些系统上,它们的行为与“assign”完全相同,可能会留下悬空指针。 - Dave DeLong

1
如果您正在寻找对您发布的代码的清晰解释,我可以尝试帮助您。我发布了一个类似的问题,提出了一个假设,等待答案来验证或否定我的假设。
我的问题在这里:Explain __weak and __strong usage reasons in SDWebImage code 总之,这就是我的想法:该代码正在初始化一个类的实例。但它需要运行异步块。__weak和__strong关键字用于确保在异步块运行时实例仍然有效。如果实例已被释放,则无需执行“setMovieDecoder”操作。
要回答您的具体问题,每当您运行需要更新某个对象实例并且您需要该实例以更新它的异步块时,您都要使用此代码模式。不要在简单下载某些内容(例如同步引擎)的异步块周围使用此代码模式。
****免责声明:检查我精炼问题的答案,希望得到上述代码模式的真正专家解释。希望我是正确的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接