以下讨论在 MRC 下。
1. 不要在 init 和 dealloc 函数中使用 accessor
dealloc 实现:
不推荐:
```objective-c
[self release];
[super dealloc];
```
推荐:
```objective-c
[self release];
```
init 实现:
不推荐:
```objective-c
[self init];
[super init];
```
推荐:
```objective-c
[self init];
```
why: 对于 init 中使用 self.name 访问器会引发其他副作用,可能会对键-值观察(KVO)的通知,或者你的子类重载了 name 的属性访问器(子类覆盖了父类的实现)。
假如 Custom 实现如下,有一个属性 count。Custom 的子类是 CustomSub,且实现如下,同时重写了父类 count 属性访问器。当你在初始化子类时:
```objective-c
self = [super init];
```
它会从 NSObject -> Custom -> CustomSub 中调用 init 分别初始化当前类的成员,你子类中重写了 Custom 属性访问器,那么就会影响 Custom 初始化自己的成员 count。这是从设计模式上来说,子类不应该去影响父类初始化自己的成员。这样可能导致其他问题。如果我们中规中矩地这么写,可能不会出现问题。那我要想使坏,那...你懂的。。所以我们应该在 init 或 dealloc 中使用 _count 直接访问属性,则不会出现上述问题。在 dealloc 中使用 self.count:有可能 count 的生命周期已经结束,不能再接受消息。上面是从其它文章中拷过来的,我没太明白是在什么样的情况下,按理说对一个 nil 对象发送 release 消息不会有问题。我个人理解:其实 init、dealloc 中不建议使用访问器而直接使用 _property 的根本原因是子类不应该去影响父类初始化和释放自己资源(property),通过上面可知子类覆盖父类属性访问器的后果,使用 _property 可以有效避免一些未知错误。
2. 为什么 [super dealloc]; 要放在最后?
释放类的内存是在 NSObject 里定义的,释放顺序应该是先释放本类里的 source,再调用父类中的 dealloc。应该本类中可能拥有不止一个父类,沿着继承链依次释放父类中的资源。这个过程和 init 过程相反,注:可以把 init 过程比作生成一个洋葱,从最核心的 NSObject(分配内存、初始化属性。)外层逐层初始化自己的东西,直到本类......
同理,dealloc 可以比作剥洋葱。在编程中,解构赋值(dealloc)是一种将数组或结构体中的元素分解为单独的变量的过程。这就像剥开一个洋葱,一层一层地将外层的皮剥掉,直到找到内部的实质。同样,在使用解构赋值时,我们需要逐层解构,先从最外层的数组或结构体开始,然后逐步深入到内部的结构体或数组,直到最后得到我们需要的元素。
以下是一个使用 C++ 语言的解构赋值示例:
```cpp
#include
int main() {
// 定义一个结构体
struct Point {
int x;
int y;
};
// 创建一个结构体数组
Point points[] = { {3, 4}, {5, 6}, {7, 8} };
// 使用解构赋值提取结构体的成员
int a = points[0].x;
int b = points[0].y;
int c = points[1].x;
int d = points[1].y;
int e = points[2].x;
int f = points[2].y;
// 输出结果
std::cout << "a: " << a << ", b: " << b << std::endl;
std::cout << "c: " << c << ", d: " << d << std::endl;
std::cout << "e: " << e << ", f: " << f << std::endl;
return 0;
}
```
在这个示例中,我们定义了一个名为 `Point` 的结构体,包含两个整数成员 `x` 和 `y`。然后,我们创建了一个 `Point` 类型的数组 `points`,并用一些示例数据初始化它。接下来,我们使用了解构赋值语法 `points[i].x`、`points[i].y` 将结构体的成员提取到单独的变量 `a`、`b`、`c`、`d`、`e` 和 `f`。最后,我们输出这些变量的值。