Objective c 调度异步队列中的薄弱环节(调度获取主队列(),^{})

Objective c 调度异步队列中的薄弱环节(调度获取主队列(),^{}),objective-c,objective-c-blocks,weak-references,retain-cycle,strong-references,Objective C,Objective C Blocks,Weak References,Retain Cycle,Strong References,下面的代码片段位于目标C中 __weak MyView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.activityIndicatorView stopAnimating]; [weakSelf.activityIndicatorView removeFromSuperview]; weakSelf.activityIndicatorView = nil; }); we

下面的代码片段位于目标C中

__weak MyView *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf.activityIndicatorView stopAnimating];
    [weakSelf.activityIndicatorView removeFromSuperview];
    weakSelf.activityIndicatorView = nil;
});
  • weakSelf
    是否始终可用/有效,因为它位于主目录中 排队
  • 我们是否只需要在块为“其他”时声明
    strongSelf
    比主队长

  • 您的代码片段太小,无法完全回答您的问题

  • weakSelf
    可以是
    nil
    或非nil。关键字
    weak
    表示变量
    weakSelf
    在某些情况下可以变成
    nil
    。例如,如果控制器具有以下属性:

    @property (retain) MyView* myView;
    
    在某些情况下,您会关闭此控制器,然后为
    myView
    调用方法
    f

    [self dismissViewControllerAnimated:YES completion:^{
    
        [self.myView f];
    }];
    
    方法f的代码基于您在本问题中提供的代码:

    -(void)f {
    
        [self removeFromSuperview];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    
            __weak MyView *weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
    
                [weakSelf.activityIndicatorView stopAnimating];
                [weakSelf.activityIndicatorView removeFromSuperview];
                weakSelf.activityIndicatorView = nil;
            });
        });
    }
    
    我猜您将在调试器中看到,当您尝试调用
    停止动画设置
    以查看
    活动指示灯时,
    弱自身将为
    nil
    。我想你可以很容易地重现当
    weakSelf
    未被清除时的情况。这意味着第一个问题的答案是“否,
    weakSelf
    并不总是可用/有效,并且主线程不会在此变量中保护您免受
    nil

  • 如果不想失去对块内变量的引用,则需要使用
    strongSelf
    \uuuu-strong
    而不是
    \uu-weak
    )。例如,如果在类
    MyView
    中有一个方法
    log
    记录一些调试信息:

    -(void)log {
    
        NSLog(@"LOG");
    }
    
    如果要始终在调用代码段中的代码之后记录信息,请使用以下版本的方法
    f

    -(void)f {
    
        [self removeFromSuperview];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    
            __strong MyView *weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
    
                [weakSelf.activityIndicatorView stopAnimating];
                [weakSelf.activityIndicatorView removeFromSuperview];
                weakSelf.activityIndicatorView = nil;
                [weakSelf log];
            });
        });
    }
    
    因此,第二个问题的答案是“不,您需要使用
    \uu strong
    ,根据您的应用程序,可以在不同的线程中完成块”


  • 您的代码片段太小,无法完全回答您的问题

  • weakSelf
    可以是
    nil
    或非nil。关键字
    weak
    表示变量
    weakSelf
    在某些情况下可以变成
    nil
    。例如,如果控制器具有以下属性:

    @property (retain) MyView* myView;
    
    在某些情况下,您会关闭此控制器,然后为
    myView
    调用方法
    f

    [self dismissViewControllerAnimated:YES completion:^{
    
        [self.myView f];
    }];
    
    方法f的代码基于您在本问题中提供的代码:

    -(void)f {
    
        [self removeFromSuperview];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    
            __weak MyView *weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
    
                [weakSelf.activityIndicatorView stopAnimating];
                [weakSelf.activityIndicatorView removeFromSuperview];
                weakSelf.activityIndicatorView = nil;
            });
        });
    }
    
    我猜您将在调试器中看到,当您尝试调用
    停止动画设置
    以查看
    活动指示灯时,
    弱自身将为
    nil
    。我想你可以很容易地重现当
    weakSelf
    未被清除时的情况。这意味着第一个问题的答案是“否,
    weakSelf
    并不总是可用/有效,并且主线程不会在此变量中保护您免受
    nil

  • 如果不想失去对块内变量的引用,则需要使用
    strongSelf
    \uuuu-strong
    而不是
    \uu-weak
    )。例如,如果在类
    MyView
    中有一个方法
    log
    记录一些调试信息:

    -(void)log {
    
        NSLog(@"LOG");
    }
    
    如果要始终在调用代码段中的代码之后记录信息,请使用以下版本的方法
    f

    -(void)f {
    
        [self removeFromSuperview];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    
            __strong MyView *weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
    
                [weakSelf.activityIndicatorView stopAnimating];
                [weakSelf.activityIndicatorView removeFromSuperview];
                weakSelf.activityIndicatorView = nil;
                [weakSelf log];
            });
        });
    }
    
    因此,第二个问题的答案是“不,您需要使用
    \uu strong
    ,根据您的应用程序,可以在不同的线程中完成块”