문제

My intention is to compare CGPoints or CGPoint values (and as the app is also for Mac OS NSPoints or NSPoint values) of several moving objects to detect if the objects have the same position.

My first solution to this was to fast enumerate an array of those objects and store all CGPoints to an array, then fast enumerate the array of objects again to check whether the position is the same of any other object:

// STEP 1: Collect all Positions
NSMutableArray *allPositions = [NSMutableArray arrayWithCapacity:self.allObjects.count];
for (Object *myObject in self.allObjects) {
    CGPoint myObjectPosition = ...;
    [allPositions addObject:myObjectPosition]; // Problem here
}

// STEP 2: Check for Overlapping
for (Object *myObject in self.allObjects) {
    CGPoint myObjectPosition = ...;
    if ([allPositions containsObject:myObjectPosition] {
        // Overlapping
    }
}

The problem with this is adding the points to the allPositions Array. Therefore NSValue can be used:

[NSValue valueWithCGPoint:point];

But this does work only under iOS, for Mac OS there has to be used valueWithPoint and NSPoint.

Can I save maybe save the x and the y values in dictionaries and store them to the allPositions Array? Or is there an even better solution without having 2x fast enumerations? There are about 100 objects in self.allObjects...

도움이 되었습니까?

해결책

CGPoint and NSPoint are the same struct. It doesn't matter if they got a different name, they both hold two CGFloat. They got the same size and the same alignment, and therefore they can be used interchangeably. So in your case valueWithPoint: fits.

Edit

About the second thing you ask, this should be done with macros:

#if TARGET_OS_IPHONE
    value= [NSValue valueWithCGPoint: point];
#else 
    value= [NSValue valueWithPoint: point];
#endif

Getting the point back:

#if TARGET_OS_IPHONE
    point= value.CGPointValue;
#else
    point= value.pointValue;
#endif

http://sealiesoftware.com/blog/archive/2010/8/16/TargetConditionalsh.html

다른 팁

While working on universal iOS/OSX app i solved this problem by using NSValue category. NSValue+CGPoint.h:

@interface NSValue (CGPoint)
#if TARGET_OS_MAC
+ (NSValue *)valueWithCGPoint:(CGPoint)point;
- (CGPoint)CGPointValue;
#endif
@end

NSValue+CGPoint.m:

#import "NSValue+CGPoint.h"
@implementation NSValue (CGPoint)
#if TARGET_OS_MAC
+ (NSValue *)valueWithCGPoint:(CGPoint)point {
    return [NSValue valueWithPoint:point];
}

- (CGPoint)CGPointValue {
    return [self pointValue];
}
#endif
@end

Now i can use the same code on both iOS and Mac, for example:

// store point in NSValue
CGPoint p = {10, 10};
NSValue *v = [NSValue valueWithCGPoint:p];

// read point from NSValue
CGPoint p2 = [v CGPointValue];
//NSGeometry.h  
  typedef CGPoint NSPoint;

//CGGeometry.h
struct CGPoint {
  CGFloat x;
  CGFloat y;
};
typedef struct CGPoint CGPoint;

NSPoint and CGpoint are same;

// NSValue/+valueWithPoint:(NSPoint)point is available on Mac OS X
// NSValue/+valueWithCGPoint:(CGPoint)point is available on iOS


//save value in CGPoint

if([NSValue respondsToSelector:@selector(valueWithPoint:)])
{
    NSPoint lPoint = NSPointFromCGPoint(lCGPoint);
    // do some op
}
else {
    // do some op
}

EDIT

Dont use respondsToSelector, use TARGET_OS_IPHONE macro.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top