这些指针的有效性
Validity of these pointers
我目前正在努力提高对指针和 ARC 的掌握。
考虑以下示例
@implementation Foobar
-(NSArray *)methodA {
return self.someArray;
}
-(NSArray *)methodB {
return [[NSArray alloc] init];
}
@end
@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
现在 fooMethod
class foo
有数组的两个强属性 myArrayA
和 myArrayB
现在 myArrayA
引用了一个强数组来自 class 实例 foobar
的指针,但是 myArrayB
正在引用一个在作用域中创建的强指针。现在假设以某种方式调用了实例 f 的析构函数。当调用该析构函数时,它将清除 SomeArray
的内容,从而使 myArrayA
无效,但是由于其析构函数不知道 MethodB
分配的内存,因此内存仍然存在。我的理解是,如果实例 f 在语句 2 之后被销毁,则 myArrayA 指向的地址将无效,而 myArrayB 指向的地址将有效。如果我的理解正确,请告诉我。
假设f
是foobar
的一个实例,当你调用[f MethodA]
(并且方法名应该命名为likeThis
)时,它将return self.SomeArray;
。 self.myArrayA
将保存一个指向数组 returned 的强指针,无论 f 的状态如何(是否 dealloc
ed)。
同样地,[f MethodB]
returns [[NSArray alloc]init]
,所以 self.myArrayB
将持有指向您刚刚创建的那个实例的强指针,它将一直持有到您将 self.myArrayB
设置为零。
在Objective-C中,当一个对象不复存在时调用的方法叫做dealloc
,我们倾向于简称为dealloc
,不要不要称它为 "destructor",尽管 dealloc
非常接近于其他语言的析构函数。
然而,话虽如此,ARC 禁止您直接调用对象上的 dealloc
。如果您直接在一个对象上调用 dealloc
,如果您使用的是 ARC,您的项目将不会编译。
相反,ARC 写入您的内存管理代码。在某个对象的剩余强引用为零之后的某个时刻(不能保证立即发生),ARC 将释放您的对象。但重要的是,一个对象可以有 任意数量 的强引用。那么,让我们看一下您的具体示例。
在您的示例中,f
是 class Foobar
的已实例化实例,它具有 属性 someArray
。您无法显示 属性 的声明方式,但我们假设它的声明方式与 Foo
中的属性声明方式相同(如 strong
)。在任何时候 someArray
属性 变为非零,至少有一个对该数组的强引用。
为了论证,我们假设 f
是对该数组的唯一强引用。这将使数组的引用计数等于一。
现在,在 Foo
中,我们将 myArrayA
设置为 f
的 someArray
属性。这个数组现在有两个强引用——引用计数等于二。
同时,Foo
的 myArrayB
被设置为等于新实例化的 NSArray
对象。 f
没有保留对此数组的强引用。一旦 methodB
returns,只有 Foo
class 的 myArrayB
对数组具有强引用。它的引用计数等于一。
现在,假设我们保留 f
(通过任何方式),但我们的 Foo
实例被释放(但是),这两个数组会发生什么?
因为我们的 Foo
实例被释放,它将不再持有对任一数组的强引用。 ARC 会将每个数组的引用计数减一。
Foo
的 myArrayA
的引用计数将从 2 减为 1--f
仍然持有强引用,数组不会被释放。
Foo
的 myArrayB
的引用计数将从 1 减为 0——没有其他对象持有对 myArrayB
的强引用,因此引用计数为零, ARC 将释放此数组。
我目前正在努力提高对指针和 ARC 的掌握。 考虑以下示例
@implementation Foobar
-(NSArray *)methodA {
return self.someArray;
}
-(NSArray *)methodB {
return [[NSArray alloc] init];
}
@end
@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
现在 fooMethod
class foo
有数组的两个强属性 myArrayA
和 myArrayB
现在 myArrayA
引用了一个强数组来自 class 实例 foobar
的指针,但是 myArrayB
正在引用一个在作用域中创建的强指针。现在假设以某种方式调用了实例 f 的析构函数。当调用该析构函数时,它将清除 SomeArray
的内容,从而使 myArrayA
无效,但是由于其析构函数不知道 MethodB
分配的内存,因此内存仍然存在。我的理解是,如果实例 f 在语句 2 之后被销毁,则 myArrayA 指向的地址将无效,而 myArrayB 指向的地址将有效。如果我的理解正确,请告诉我。
假设f
是foobar
的一个实例,当你调用[f MethodA]
(并且方法名应该命名为likeThis
)时,它将return self.SomeArray;
。 self.myArrayA
将保存一个指向数组 returned 的强指针,无论 f 的状态如何(是否 dealloc
ed)。
同样地,[f MethodB]
returns [[NSArray alloc]init]
,所以 self.myArrayB
将持有指向您刚刚创建的那个实例的强指针,它将一直持有到您将 self.myArrayB
设置为零。
在Objective-C中,当一个对象不复存在时调用的方法叫做dealloc
,我们倾向于简称为dealloc
,不要不要称它为 "destructor",尽管 dealloc
非常接近于其他语言的析构函数。
然而,话虽如此,ARC 禁止您直接调用对象上的 dealloc
。如果您直接在一个对象上调用 dealloc
,如果您使用的是 ARC,您的项目将不会编译。
相反,ARC 写入您的内存管理代码。在某个对象的剩余强引用为零之后的某个时刻(不能保证立即发生),ARC 将释放您的对象。但重要的是,一个对象可以有 任意数量 的强引用。那么,让我们看一下您的具体示例。
在您的示例中,f
是 class Foobar
的已实例化实例,它具有 属性 someArray
。您无法显示 属性 的声明方式,但我们假设它的声明方式与 Foo
中的属性声明方式相同(如 strong
)。在任何时候 someArray
属性 变为非零,至少有一个对该数组的强引用。
为了论证,我们假设 f
是对该数组的唯一强引用。这将使数组的引用计数等于一。
现在,在 Foo
中,我们将 myArrayA
设置为 f
的 someArray
属性。这个数组现在有两个强引用——引用计数等于二。
同时,Foo
的 myArrayB
被设置为等于新实例化的 NSArray
对象。 f
没有保留对此数组的强引用。一旦 methodB
returns,只有 Foo
class 的 myArrayB
对数组具有强引用。它的引用计数等于一。
现在,假设我们保留 f
(通过任何方式),但我们的 Foo
实例被释放(但是),这两个数组会发生什么?
因为我们的 Foo
实例被释放,它将不再持有对任一数组的强引用。 ARC 会将每个数组的引用计数减一。
Foo
的 myArrayA
的引用计数将从 2 减为 1--f
仍然持有强引用,数组不会被释放。
Foo
的 myArrayB
的引用计数将从 1 减为 0——没有其他对象持有对 myArrayB
的强引用,因此引用计数为零, ARC 将释放此数组。