0

我试图找出objective-c中的两个矩形之间是否发生碰撞。我认为实现这一点的一种方法是检测最接近 0,0 点的矩形,然后做剩下的工作。

我写了一个函数,它接受两个矩形对象作为参数,并进行数学计算来计算面积、到原点的距离等......

因此,假设 rect1 位于 (100,200) 且 rect1 的宽度为 100 高度 200,rect2 位于 150,150 且 rect2 的宽度为 100 高度 200,这是由函数计算得足够好。

如果我切换 rec1 和 rect2 属性,那么 rect1 将是 150,150,而 rect2 将是 100,200。并调用以下函数

-(Rectangle*)intersect:(Rectangle*)rectA:(Rectangle*)rectB{    
    //check closest rectangle to 0,0 and switch rectangles
    if (rectA.origin.x>rectB.origin.x) {
        Rectangle *temporary = [[Rectangle alloc] init];
        temporary=rectA;
        rectA=rectB;
        rectB=temporary;
        [temporary release];
    }

    float rectAX = rectA.origin.x;
    float rectAY = rectA.origin.y;

    float rectBX = rectB.origin.x;
    float rectBY = rectB.origin.y;

当我启用保护 malloc 和僵尸时,出现以下错误: -[Rectangle origin]: message sent to deallocated instance 0x100acffd0

一旦rectA.origin.x;被调用,我就会得到错误。

那么 rectA 或 rectB 是如何被释放的呢?切换具有一堆属性的两个对象的正确方法是什么?

4

3 回答 3

2

有一个用于比较 CGRects 的内置函数CGRectIntersectsRect(rectA, rectB),您可以使用它来检查矩形的框架:)

至于您的切换代码,您已经通过分配临时创建了第三个对象。然后将临时指针设置在 rectA 处,然后在最后释放 rectA,因为它指向临时。将新创建的对象作为泄漏,然后将消息发送到释放的 rectA。

如果您可以根据我的经验提供帮助,您真的不想像那样交换对象指针。但是,如果您绝对必须并了解正在发生的事情,您可以这样做:

// Create copies of your objects
Rectangle *rectACopy = [rectA copy];
Rectangle *rectBCopy = [rectB copy];

// release the originals.
[rectA release];
[rectB release];

// Set your copies to the original pointers.
rectA = rectBCopy;
rectB = rectACopy;

NSCopying 协议

首先你需要实现协议。

@interface Rectangle : NSObject <NSCopying>

然后您需要创建新方法。这将创建一个新对象,但具有所有相同的值。

- (id)copyWithZone:(NSZone *)zone
{
    id copy = [[[self class] alloc] init];

    if (copy) {
        // Copy NSObject based properties like UIViews, NSArrays, Subclassed objects.
        [copy setObjectProperty:[self.objectProperty copy]];

        // Set primitives like ints, CGRects, Bools.
        [copy setPrimitiveProperty:self.primitiveProperty];
    }

    return copy;
}
于 2012-12-11T15:12:33.060 回答
1

您不需要为其分配新的对象实例temporary(因此您也不需要释放它)。你只是拿你的 2 个现有指针并切换它们。使用第三个变量 ( temporary) 是正确的,但您不需要分配任何新空间,因为您没有在内存中移动任何内容,只是交换哪些变量指向现有对象。

于 2012-12-11T15:18:51.190 回答
1
-(Rectangle*)intersect:(Rectangle*)rectA:(Rectangle*)rectB{    
    //check closest rectangle to 0,0 and switch rectangles
    if (rectA.origin.x>rectB.origin.x) {
        //Rectangle *temporary = [[Rectangle alloc] init]; // here you don't need to allocate as you are not using this object
        // So use 
        Rectangle *temporary=rectA;
        rectA=rectB;
        rectB=temporary;
        //[temporary release]; //you don't need this. Here you were releasing rectA not the temp rect that you allocated just below if, as you assign rectA to temporary
    }

    float rectAX = rectA.origin.x;
    float rectAY = rectA.origin.y;

    float rectBX = rectB.origin.x;
    float rectBY = rectB.origin.y;
于 2012-12-11T15:30:30.670 回答