Mord Fustang
Mord Fustang

Reputation: 1553

How to switch two objects in objective-c

I am trying to find if collision occurs between two rectangles in objective-c. I thought one way to accomplish this would be detect the rectangle that is closest to 0,0 point then do rest of the work.

I wrote a function that takes two rectangle objects as parameters and does the math to calculate area, distance to origin etc....

So lets say rect1 is at (100,200) and rect1's width is 100 height 200, rect2 is at 150,150 and rect2's width is 100 height 200 this is calculated by function well enough.

If I switch rec1 and rect2 properties, so rect1 will be at 150,150 while rect2 will be at 100,200. And call following function

-(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;

When I enable guard malloc and zombies I get following error: -[Rectangle origin]: message sent to deallocated instance 0x100acffd0

As soon as rectA.origin.x; is called I get the error.

So Howcome rectA or rectB is deallocated? What is the correct way to switch two objects that has bunch of properties ?

Upvotes: 0

Views: 181

Answers (3)

Ryan Poolos
Ryan Poolos

Reputation: 18551

There is a built in function for comparing CGRects CGRectIntersectsRect(rectA, rectB) that you can use to check your rectangle's frames :)

As far as your code for switching you have created a third object by allocing temporary. Then you set the temporary pointer at rectA and then you release rectA at the end since its pointing to temporary. Leaving the newly created object as a leak and then sending messages to the released rectA.

You don't really want to swap object pointers like that if you can help it in my experience. But if you absolutely have to and understand what's going on you could do it like this:

// 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 Protocol

First you need to implement the protocol.

@interface Rectangle : NSObject <NSCopying>

Then you need to create the new method. This will create a new object but with all the same values.

- (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;
}

Upvotes: 2

Inder Kumar Rathore
Inder Kumar Rathore

Reputation: 39988

-(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;

Upvotes: 1

Martin
Martin

Reputation: 5452

You don't need to allocate a new object instance for temporary (and therefore you don't need to release it either). You are just taking your 2 existing pointers and switching them around. You're correct to use a 3rd variable (temporary) but you don't need to allocate any new space because you're not moving anything in memory, just swapping which variables point to the existing objects.

Upvotes: 1

Related Questions