Ios 零软弱的自我——为什么它';发生什么事了?
我想在区块中使用弱自我,但在区块中,弱自我变成零 刚创建,在块之前(尝试使用不同的变体)-看起来一切正常 但后来在block中,每个变体都是nil 哪里做错了?有人能解释一下吗 编辑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
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
模式还是很谨慎的,因为它准确地反映了适当的对象图(块没有“拥有”和/或维护视频播放器强引用的业务)