将局部变量分配给实例变量的 ARC 行为
ARC behavior on assigned local variable to an instance variable
问题 1
假设我有这个代码:
MyClass * __strong foo = [MyClass new];
MyClass * __strong bar = foo;
// foo = nil; // by ARC?
在引用 this answer 时,ARC
是否会自动将第 3 行的 foo
归零,因为 bar
已经获取了引用?
问题 2
//ECGService.m
@property (strong) MuttableArray *rriData;
(MuttableArray *)getRriData {
return _rriData;
}
//AlgorithmTest.m
// according to Apple docs, local variable are marked __strong by default
MuttableArray *rriData = [self.ecgService getRriData];
for(NSNumber *rri in rriData) {
// use rri!
}
// rriData = nil;
局部变量rriData
用完后是不是应该nil掉?
而且,__strong
属性是否只能应用于一个对象的一个实例?
问题 1。不,您只是以两个对 MyClass 实例的引用结束。什么都没有消失。
问题 2。不,您不需要取消任何内容。 ARC 为您管理内存。这才是重点。您也永远不需要说 __strong
。这是默认值。
In reference to this answer, does ARC automatically nil out foo on line 3 since bar already acquired the reference?
没有。 ARC 代表自动参考 计数 。显然计数不止于 1.
ARC 的优势在于每个引用都独立于其他引用进行处理。强 foo
保留被引用的对象,只要它指向。其他引用变量是否指向同一个对象并不重要。跟踪每个孤立的参考。
只有一种情况让ARC改变一个引用变量的值:如果它被标记为weak
并且没有其他对该对象的强引用。这是预期的行为。
作为优化的结果,保留和释放可能被省略,或者源代码中的不同局部变量被放在一起。这对你来说是透明的。
Should I nil out the local variable rriData after using it?
你不应该关心这个。强引用变量会自动保留一个对象,其引用存储在引用变量中。如果它不再指向它,它会自动释放该对象。这包括
上的版本
- 一个新值被赋给了引用变量
nil
赋值给引用变量
- 引用变量失去它的范围(生命周期)。
由于最后一个事实,当rriData
失去它的范围时,会有一个自动生成的版本。没有理由提前取消它。
答案 1.
原则上,ARC 在超出范围之前不会“消失”foo
。当它超出范围时,ARC 释放它的引用。它不必实际将 foo
设置为 nil,但效果就像 ARC 确实将其设置为 nil 一样。
实际上,通常允许 ARC 在最后一次使用 foo
变量后立即释放 foo
持有的引用,这可能在它超出范围之前很久。在您的示例中,如果您在函数中唯一使用 foo
的地方是在对 bar
的赋值中,则允许 ARC 在该赋值后立即释放 foo
的引用。请注意,通常您无法知道此早期版本,因为您不再使用 foo
!另请注意 bar
仍将引用该对象,除非 bar
稍后也未在函数中使用。
有一些特殊属性可以阻止 ARC 执行此早期版本,称为 objc_precise_lifetime
和 objc_returns_inner_pointer
,但通常通过宏 NS_VALID_UNTIL_END_OF_SCOPE
和 NS_RETURNS_INNER_POINTER
应用。这些是您可能很快就不必担心的高级功能,但如果您想查看 NS_RETURNS_INNER_POINTER
的一些示例,请查看 NSString.h
.
答案 2.
你不需要“nil out”rriData
。 ARC 将在超出范围时释放其引用(或更早 - 请参阅答案 1)。
你通常不需要说__strong
,因为它是默认的,而且它通常是你想要的。对一个对象有多个强引用是正常的。当您需要防止保留循环时,您可以显式使用 __weak
。关于retain cycles在网上和stack overflow上有很多解释,如果你需要了解它们,请访问你喜欢的搜索引擎。
问题 1
假设我有这个代码:
MyClass * __strong foo = [MyClass new];
MyClass * __strong bar = foo;
// foo = nil; // by ARC?
在引用 this answer 时,ARC
是否会自动将第 3 行的 foo
归零,因为 bar
已经获取了引用?
问题 2
//ECGService.m
@property (strong) MuttableArray *rriData;
(MuttableArray *)getRriData {
return _rriData;
}
//AlgorithmTest.m
// according to Apple docs, local variable are marked __strong by default
MuttableArray *rriData = [self.ecgService getRriData];
for(NSNumber *rri in rriData) {
// use rri!
}
// rriData = nil;
局部变量rriData
用完后是不是应该nil掉?
而且,__strong
属性是否只能应用于一个对象的一个实例?
问题 1。不,您只是以两个对 MyClass 实例的引用结束。什么都没有消失。
问题 2。不,您不需要取消任何内容。 ARC 为您管理内存。这才是重点。您也永远不需要说 __strong
。这是默认值。
In reference to this answer, does ARC automatically nil out foo on line 3 since bar already acquired the reference?
没有。 ARC 代表自动参考 计数 。显然计数不止于 1.
ARC 的优势在于每个引用都独立于其他引用进行处理。强 foo
保留被引用的对象,只要它指向。其他引用变量是否指向同一个对象并不重要。跟踪每个孤立的参考。
只有一种情况让ARC改变一个引用变量的值:如果它被标记为weak
并且没有其他对该对象的强引用。这是预期的行为。
作为优化的结果,保留和释放可能被省略,或者源代码中的不同局部变量被放在一起。这对你来说是透明的。
Should I nil out the local variable rriData after using it?
你不应该关心这个。强引用变量会自动保留一个对象,其引用存储在引用变量中。如果它不再指向它,它会自动释放该对象。这包括
上的版本- 一个新值被赋给了引用变量
nil
赋值给引用变量- 引用变量失去它的范围(生命周期)。
由于最后一个事实,当rriData
失去它的范围时,会有一个自动生成的版本。没有理由提前取消它。
答案 1.
原则上,ARC 在超出范围之前不会“消失”foo
。当它超出范围时,ARC 释放它的引用。它不必实际将 foo
设置为 nil,但效果就像 ARC 确实将其设置为 nil 一样。
实际上,通常允许 ARC 在最后一次使用 foo
变量后立即释放 foo
持有的引用,这可能在它超出范围之前很久。在您的示例中,如果您在函数中唯一使用 foo
的地方是在对 bar
的赋值中,则允许 ARC 在该赋值后立即释放 foo
的引用。请注意,通常您无法知道此早期版本,因为您不再使用 foo
!另请注意 bar
仍将引用该对象,除非 bar
稍后也未在函数中使用。
有一些特殊属性可以阻止 ARC 执行此早期版本,称为 objc_precise_lifetime
和 objc_returns_inner_pointer
,但通常通过宏 NS_VALID_UNTIL_END_OF_SCOPE
和 NS_RETURNS_INNER_POINTER
应用。这些是您可能很快就不必担心的高级功能,但如果您想查看 NS_RETURNS_INNER_POINTER
的一些示例,请查看 NSString.h
.
答案 2.
你不需要“nil out”rriData
。 ARC 将在超出范围时释放其引用(或更早 - 请参阅答案 1)。
你通常不需要说__strong
,因为它是默认的,而且它通常是你想要的。对一个对象有多个强引用是正常的。当您需要防止保留循环时,您可以显式使用 __weak
。关于retain cycles在网上和stack overflow上有很多解释,如果你需要了解它们,请访问你喜欢的搜索引擎。