就像屏幕截图所描述的那样。
//
// ViewController.m
// Test
//
// Created by jam on 15/11/4.
// Copyright © 2015年 Baidu Inc. All rights reserved.
//
#import "ViewController.h"
#import "CJTestObject.h"
@interface ViewController ()
@property (strong, nonatomic) CJTestObject *testObject1;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_testObject1 = [[CJTestObject alloc] init];
CJTestObject *testObject2 = [[CJTestObject alloc] init];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"_testObject1: %@", _testObject1);
NSLog(@"testObject2: %@", testObject2);
});
_testObject1 = nil;
testObject2 = nil;
}
@end
控制台输出
2015-11-20 18:07:28.855 Test[33585:417965] _testObject1: (null)
2015-11-20 18:07:28.857 Test[33585:417965] testObject2: <CJTestObject: 0x79f564f0>
我的问题是这两种变量在块中引用的不同之处。
答案 0 :(得分:2)
在你的情况下,你有这两个对象类型的变量,所以你的块应该保留在你的情况下。
但这里的主要区别是testObject2
(在方法范围中声明的变量)将被保留,但是当您在块中捕获_testObject1
时,它会保留self
而不是{ {1}}(在您的示例中)。
在块中捕获实例变量会导致保留_testObject1
,因此当此块存在时,block将保留对self
的强引用。
复制块时,它们引用的任何本地对象变量都会自动保留。然后在块被破坏时自动释放它们。这样可以确保引用保持有效。对self
的任何引用都是对本地对象变量的引用,导致self
被保留。对实例变量的任何引用都是对self
的隐式引用,并导致同样的事情。
您可以在这个精彩的博客中找到更多详情
https://mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html
更新: 至于你的控制台输出,当块执行时会发生什么:
self
这里需要复制对NSLog(@"testObject1: %@", _testObject1);
的引用,并在执行时取消引用它的_testObject1实例变量&#34;指针&#34;。在C中它看起来像self
。
您将_testObject1的引用设置为nil,在2秒后,您的块会查看此更新的&#39;参考
self->_testObject1
这里你的块复制并保留了对testObject2的引用。设置testObject2 = nil时,将变量的引用设置为nil。但是阻止仍然复制了#39;并保留地址到您的变量,因此它存储并打印该值。
看起来有点复杂但我希望能理解我的答案:)