Ios 零软弱的自我——为什么它';发生什么事了?

Ios 零软弱的自我——为什么它';发生什么事了?,ios,objective-c,block,null,weak,Ios,Objective C,Block,Null,Weak,我想在区块中使用弱自我,但在区块中,弱自我变成零 刚创建,在块之前(尝试使用不同的变体)-看起来一切正常 但后来在block中,每个变体都是nil 哪里做错了?有人能解释一下吗 编辑 SPHVideoPlayer *videoPlayer = [[SPHVideoPlayer alloc] initVideoPlayerWithURL:urlToFile]; [videoPlayer prepareToPlay]; 初始化 #pragma mark - LifeCycle - (inst

我想在区块中使用弱自我,但在区块中,弱自我变成零

刚创建,在块之前(尝试使用不同的变体)-看起来一切正常

但后来在block中,每个变体都是nil

哪里做错了?有人能解释一下吗

编辑

SPHVideoPlayer *videoPlayer = [[SPHVideoPlayer alloc] initVideoPlayerWithURL:urlToFile];
[videoPlayer prepareToPlay];
初始化

#pragma mark - LifeCycle

- (instancetype)initVideoPlayerWithURL:(NSURL *)urlAsset
{
    if (self = [super init]) {
        [self initialSetupWithURL:urlAsset];
    }
    return self;
}

- (void)initialSetupWithURL:(NSURL *)url
{
    NSDictionary *assetOptions = @{ AVURLAssetPreferPreciseDurationAndTimingKey : @YES };
    self.urlAsset = [AVURLAsset URLAssetWithURL:url options:assetOptions];
}
以及采用分块的方法

- (void)prepareToPlay
{
    __weak typeof(self) weakSelf = self;
    __weak SPHVideoPlayer *weakSealf2 = self;
    NSArray *keys = @[@"tracks"];
    [self.urlAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf startLoading];
        });
    }];
}

块具有弱引用的原因是不保留块中的类。 当实例不再存在时,弱引用得到nil,因此您需要相应地处理弱引用(在代码中这样做)。
如果这不是您想要实现的,那么您需要确保您的实例没有被解除分配,但这与您的块无关……

对块具有弱引用的原因是不将类与块一起保留。 当实例不再存在时,弱引用得到nil,因此您需要相应地处理弱引用(在代码中这样做)。
如果这不是您想要实现的,那么您需要确保您的实例没有被解除分配,但这与您的块无关…

这就是弱变量的概念:弱变量不包含引用计数,因此如果弱变量是唯一保留对象的对象,对象将被释放,弱变量将为nil。这就是弱变量的工作方式和使用方式

如果您使用了强引用,那么您的代码块将是唯一一个仍保留在self上的代码,并且您对self所做的所有工作都将毫无意义,因为没有其他人会注意到它。因为您使用的是弱变量,所以可以通过检查变量是否为nil来避免这种情况


在多线程环境中,最后一个强引用可能随时消失,而弱引用可能随时变为零。通过将弱变量复制到强变量中作为块中的第一件事来避免这种情况,这样您就知道弱变量可能在进入块之前就消失了,但在块执行时它不会消失

这就是弱变量的概念:弱变量不包含引用计数,因此,如果一个弱变量是唯一保留对象的对象,那么该对象将被解除分配,弱变量将为零。这就是弱变量的工作方式和使用方式

如果您使用了强引用,那么您的代码块将是唯一一个仍保留在self上的代码,并且您对self所做的所有工作都将毫无意义,因为没有其他人会注意到它。因为您使用的是弱变量,所以可以通过检查变量是否为nil来避免这种情况


在多线程环境中,最后一个强引用可能随时消失,而弱引用可能随时变为零。通过将弱变量复制到强变量中作为块中的第一件事来避免这种情况,这样您就知道弱变量可能在进入块之前就消失了,但在块执行时它不会消失

正如rckoenes所建议的,这个
sphdevideoplayer
已经超出范围,即将发布。假设您不希望它被发布,您只需要选择一个保持它的作用域(例如,使它成为显示视频的视图控制器的属性)

您描述了如何使用
weakSelf
来防止“保留周期”(现在通常称为“强引用周期”)。是的,
weakSelf
模式用于防止强引用循环。从技术上讲,还不完全清楚你是否一定有一个强大的参考周期。它取决于
loadValuesAsynchronousForKey…
实现的详细信息(例如,该块是否加载到某个类属性中,从而创建从类到
self
的块类属性引用的强引用循环,而该循环又保持了对
self
的强引用)

但这都有点学术性:尽管如此,
weakSelf
模式还是很谨慎的,因为它准确地反映了适当的对象图(块没有“拥有”和/或维护视频播放器的强引用的业务)。不过,巧合的是,当您使用
weakSelf
时,它也消除了强引用循环的潜在风险


真正的问题是,您可能希望不仅在加载资源时,而且在视频播放时,将视频播放器保持在范围内,因此您希望更改视频播放器的范围(大概是为了匹配显示视频播放器的视图控制器。

正如Rckones所建议的,这个
SPHVideoPlayer
超出了范围,正在被释放。假设你不想释放它,你只需要选择一个保持它在周围的范围(例如,使其成为显示视频的视图控制器的属性)

您描述了如何使用
weakSelf
来防止“保留周期”(现在通常称为“强引用周期”)是的,
weakSelf
模式用于防止强引用循环。从技术上讲,并不完全清楚您是否一定有强引用循环。这取决于
LoadValuesAsSynchronousForkey…
实现的详细信息(例如,是否将该块加载到某个类属性中,从而创建从类到
self
的块类属性引用的强引用循环,从而保持对
self
的强引用)

但这都有点学术性:尽管如此,
weakSelf
模式还是很谨慎的,因为它准确地反映了适当的对象图(块没有“拥有”和/或维护视频播放器强引用的业务)