Objective c 这些指针的有效性
我目前正在努力提高我对指针和弧线的掌握。 考虑下面的例子Objective c 这些指针的有效性,objective-c,automatic-ref-counting,Objective C,Automatic Ref Counting,我目前正在努力提高我对指针和弧线的掌握。 考虑下面的例子 @implementation Foobar -(NSArray *)methodA { return self.someArray; } -(NSArray *)methodB { return [[NSArray alloc] init]; } @end 现在在fooMethod中,类foo具有数组的两个强属性myArrayA和myArrayB现在myArrayA正在引用类实例foobar中的强指针,但是myA
@implementation Foobar
-(NSArray *)methodA {
return self.someArray;
}
-(NSArray *)methodB {
return [[NSArray alloc] init];
}
@end
现在在
fooMethod
中,类foo
具有数组的两个强属性myArrayA
和myArrayB
现在myArrayA
正在引用类实例foobar
中的强指针,但是myArrayB
正在引用在作用域中创建的强指针。现在假设以某种方式调用了实例f的析构函数。调用该析构函数时,它将清除SomeArray
的内容,从而使myArrayA
无效。但是,由于其析构函数不知道MethodB
分配的内存,因此该内存仍将处于活动状态。我的理解是,如果实例f在语句2之后被销毁,myArrayA指向的地址将无效,而myArrayB指向的地址将有效。请让我知道我的理解是否正确。假设f
是foobar
的一个实例,当您调用[f MethodA]
(方法名称应该像这样命名),它将返回self.SomeArray代码>self.myArrayA
将保留一个指向返回数组的强指针,而不管f的状态如何(如果其dealoc
ed)
同样地,[f MethodB]
返回[[NSArray alloc]init]
,因此self.myArrayB
将保留一个指向您刚刚创建的实例的强指针,直到您将self.myArrayB
设置为nil为止。假设f
是foobar
的实例,调用[f MethodA]
(方法名称应该像这样命名),它将返回self.SomeArray;
self.myArrayA
将保留一个指向返回数组的强指针,而不管f的状态如何(如果其dealloc
ed)
同样地,[f MethodB]
返回[[NSArray alloc]init]
,因此self.myArrayB
将保留一个指向您刚刚创建的实例的强指针,直到您将self.myArrayB
设置为nil为止。假设f
是foobar
的实例,调用[f MethodA]
(方法名称应该像这样命名),它将返回self.SomeArray;
self.myArrayA
将保留一个指向返回数组的强指针,而不管f的状态如何(如果其dealloc
ed)
同样地,[f MethodB]
返回[[NSArray alloc]init]
,因此self.myArrayB
将保留一个指向您刚刚创建的实例的强指针,直到您将self.myArrayB
设置为nil为止。假设f
是foobar
的实例,调用[f MethodA]
(方法名称应该像这样命名),它将返回self.SomeArray;
self.myArrayA
将保留一个指向返回数组的强指针,而不管f的状态如何(如果其dealloc
ed)
同样地,[f MethodB]
返回[[NSArray alloc]init]
,因此self.myArrayB
将保留一个指向您刚刚创建的实例的强指针,它将一直保留,直到您将self.myArrayB
设置为nil。在Objective-C中,当对象不再存在时调用的方法称为dealloc
,我们倾向于简单地将其称为dealloc
,并且不要称它为“析构函数”,尽管dealloc
与其他语言的析构函数相当接近
但是,如上所述,ARC禁止您对对象直接调用dealloc
。如果您直接对对象调用dealloc
,则如果您使用ARC,您的项目将无法编译
相反,ARC在内存管理代码中写入。在某个点之后,对象有剩余的强引用(不能保证立即发生),ARC将释放您的对象。但是重要的是,对象可以有任意数量的强引用。所以,让我们来看一下您的具体例子。
在您的示例中,
f
是类Foobar
的一个已实例化实例,它具有一个属性someArray
。您无法显示如何声明该属性,但让我们假设它的声明方式与Foo
中的属性的声明方式相同(如strong
)。无论someArray
属性在什么时候变为非nil,都至少有一个对该数组的强引用
为了便于讨论,我们假设f
是此数组的唯一强引用。这将使数组的引用计数等于1
现在,在Foo
中,我们将myArrayA
设置为f
的someArray
属性。这个数组现在有两个强引用——引用计数等于2
同时,Foo
的myArrayB
被设置为等于一个新实例化的NSArray
对象。f
不保留对该数组的强引用。只要methodB
返回,只有Foo
类的myArrayB
具有对该数组的强引用。它的引用计数等于我要一个
现在,假设我们保持f
不变(通过任何方式),但是我们的Foo
实例被解除分配(但是),这两个数组会发生什么情况
因为我们的Foo
实例被解除分配,它将不再持有对任一数组的强引用。ARC将使每个数组的引用计数减少一
Foo
的myArrayA
将其引用计数从2减少到1--f
仍然保持强引用,数组i
@interface Foo : NSObject
@property(strong) NSArray * myArrayA;
@property(strong) NSArray * myArrayB;
@end
@implementation Foo
-(void)fooMethod {
//suppose f is an instance of foobar
self.myArrayA = [f methodA]; //---->statement 1
self.myArrayB = [f methodB]; //---->statement 2
//Destructor of f instance is called.
//Will myArrayA and myArrayB be valid ?
}
@end