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