首先,我 要运行 下面这个程序:
文件XY.h:
文件XY.m:
文件Rectangle.h:
文件Rectangle.m:
文件main.m:
运行 刚刚这个程序后,会得到 这样的结果:
你 能解释 为什么 会得到 这样的结果 吗?
至此 有 一个事实 我 不得不说了。那 就是 一个存储物件的变量 并不是 存储的 物件本身,而是 存储的 物件的地址。这 就是 为什么 在上面这个程序当中myRectangle 和 myXY这两个变量 分别 属于 Rectangle *类型 和 XY *类型,而不是 Rectangle类型 和 XY类型。为了 方便,我们 还是 将 存储某个物件地址的变量 当作 这个物件本身吧。
这行语句 将 物件myXY所代表的点 设定为 (100,200)。
接下来的
这行语句 完全 相当于
这行语句,也就是 对 myRectangle这个物件 实施 setLocation这项措施,并且 将 myXY这个物件 附带为 参数。
我们 来看看 setLocation这项措施 都 包含了 什么:
其中 Pnt这个本地变量 是 用来存储参数的。所以 setLocation这项措施 一旦 实施,那么 myXY这个物件的地址 就会 被存储 在本地变量Pnt当中,接着
这行语句 就会 将 变量Pnt的值 存储 在变量location当中。由于 变量location 由myRectangle这个物件 所有,而 变量Pnt的值 又 是 物件myXY的地址,所以 物件myRectangle的变量location中 存储的 是 物件myXY的地址。因此 物件myXY所代表的点 一旦 变成 (10,20),那么 物件myRectangle的变量location所代表的位置 也就变成了 (10,20)。
为了 避免 这样的悲剧,我们 需要 对 setLocation:这样措施 作出修改:
这项措施 先 为变量location 分配 内存 并且 初始化。然后 Pnt.x 和 Pnt.y 将 物件myXY所代表的点的横坐标、纵坐标 读取出来,通过实施 setX:andY:这项措施 将 横、纵坐标 存储 在变量location当中。
重新 编译的时候,编译器 告诉 我 无法识别 .x 和 .y。原因 是 在Rectangle.h文件当中 我们 只 告诉了 编译器 XY 是 一类物件的名称,而 没有告诉 编译器 能 对XY这类物件 采取 什么措施。只需要 将 文件Rectangle.h当中的
替换成
就可以 顺利 编译了。
在腾空 物件myRectangle所占用的内存之前,还 必须 腾括 物件myRectangle所属的location这个物件所占用的内存,就像 这样:
由于 location这项措施 会将 location这个物件的地址 传递回来,所以 release这项措施 知道 location这个物件 在哪里,于是 你 可以 放心 物件location所占用的内存 能够 被清空。
再次 运行,就可以 得到 预期的结果了: