我知道但不完全是所有弧的工作方式。
我知道何时使用弱属性来防止内存泄漏。
但我想了解别的东西。
如果我在UIViewController
内有强大的自定义视图,就像这样:
@property (nonatomic) UIView myView;
(如果我们没有指定任何内容,则默认为强)。
如果这种观点很弱,我知道不需要关心释放它,但强者呢?
我的ViewController在它强大的时候显示它是否会显示/ dealloc?
1.我应该在viewWillDisappear中将此视图设置为nil吗?
2.为什么当我创建一个弱属性时,在我调用它的“init”方法后它不再存在了?
答案 0 :(得分:2)
让我们看看我们是否可以提供帮助:
如果我
UIViewController
内有强大的自定义视图,请执行以下操作:@property (nonatomic) UIView myView;
(如果我们不指定任何内容,则默认为强)。如果这种观点很弱,我知道不需要关心释放它,但强者呢?在我的ViewController didDisappear / dealloc强大后它是否仍然存活?
不要考虑引用计数或释放,ARC真的会扭转局面。 strong , weak 等属性与变量相关联,您可以通过采用以变量为中心的视图来理解这一点,其中变量是actor - 控制引用对象生命周期的实体。
当引用存储到具有strong属性的变量中时,采用此视图,然后变量通知ARC它需要引用的对象保持不变。
从变量中删除该引用;例如用另一个引用或nil
覆盖它;然后变量告诉ARC它不再需要引用的对象留在那里。
您的问题是当ARC删除具有强属性的实例变量的对象时会发生什么。采用以变量为中心的观点,问题就变成了:变量本身被破坏后会发生什么?
答案是具有强属性的变量的最后一个动作。并且存储了一个引用,告诉ARC该变量不再需要保留引用的对象。
- 我应该在viewWillDisappear中将此视图设置为nil吗?
醇>
如果变量本身在需要存储在变量中的引用所引用的对象之后很久就会继续存在,则只需要设置一个具有强属性nil
的变量。
E.g。如果你有一个很长的生命对象,它在其生命周期中在一个实例变量中短时间内存储一个大对象的引用,那么在其他时间将该变量设置为nil
是有意义的。
- 为什么当我创建一个弱属性时,在我调用它的“init”方法后它不再存在?
醇>
我在这里假设您的意思是“创建一个对象并在弱属性中存储对它的引用”。
保持以变量为中心的视图,具有weak属性的变量不会告诉ARC保持对象,就像具有strong属性的那样,而是监视引用的对象,当它消失时,它将自己设置为{ {1}}。
如果你创建一个对象,只要存在一个存储在具有strong属性的变量中的引用,它就会被ARC保留。如果您对引用所做的只是将它存储在具有弱属性的变量中,则不需要ARC来保持对象。
将变量视为上面的参与者当然是类比,变量本身不是活动实体。实际发生的是,在编译期间,编译器会插入执行上述变量操作的指令。结果是一样的。
TL; DR:强大& weak是与变量相关联的属性而不是引用。考虑变量的生命周期以及存储在其中的内容,以确定是否保留任何对象或将其删除。
HTH
答案 1 :(得分:0)
强大的参考(在大多数情况下您会使用)意味着您想拥有"拥有"您使用此属性/变量引用的对象。只要您使用强引用指向它,编译器就会注意您分配给此属性的任何对象都不会被销毁。只有将属性设置为nil后,对象才会被销毁(除非一个或多个其他对象也拥有对它的强引用)。
所以,是的,如果你不再使用它,你应该将你的强大属性设置为nil。
答案 2 :(得分:0)
Strong
由你的类“强烈”保存,也就是说,只要至少有一个类持有对该对象的引用,该对象永远不会从内存中释放出来。如果持有具有“强”的对象的类被取消分配,在您的情况下是UIViewController
,那么该对象将自动从内存中删除,您不必须设置它在dealloc中手动为零。有一个着名的例子:
想象一下,5个孩子正拿着气球,所有人都坚持着气球。只要一个孩子强有力地握住它,气球就永远不会飞走。现在,如果有5个孩子只有一个强烈地抓住气球而其他人则松散地(弱)抓住它。一旦抓住它的孩子强烈放开,气球就会飞走。 (我可能会解释一下,但我希望你理解!)
因此,对于您的第一点,除非情况需要,否则您不必每次都将其设置为nil。
答案 3 :(得分:0)
ARC正在计算strong
对象的引用。只要此计数为零,就会立即释放内存。您无需设置对nil
的引用或使用dealloc
。
如果您在示例中初始化weak
属性,则会立即释放它,因为强引用计数为零。
weak
用于打破保留周期。一个典型的例子是代表。在以下示例中,ObjectA
具有对其delegate
(ObjectB
)的强引用。这是一个保留周期,两个对象永远不会被释放:
@protocol ObjectADelegate <NSObject>
// requirements
@end
@interface ObjectA : NSObject
@property (strong) id<ObjectADelegate> delegate;
@end
@interface ObjectB : NSObject <ObjectADelegate>
@property (strong) ObjectA *instanceA;
@end
@implementation ObjectB
- (instancetype)init {
self = [super init];
if (self) {
self.instanceA = [ObjectA new];
self.instanceA.delegate = self;
}
return self;
}
@end
要解决此问题并中断保留周期,请将委托属性设置为weak
:
@interface ObjectA : NSObject
@property (weak) id<ObjectADelegate> delegate;
@end