Reputation: 17535
I'm having trouble with what must be a fairly simple task: adding objects to an NSMutableArray
in Objective-C. Here are the million ways I have tried already:
NSMutableArray* foregroundPoints;
Point point;
// Fails with "No viable conversion from 'Point' to 'id _Nonnull'"
[foregroundPoints addObject: point];
// Fails with "Cannot initialise a parameter of type 'id _Nonull' with an rvalue of type 'Point *'"
[foregroundPoints addObject: &point];
// Fails with: "Illegal type 'Point' used in boxed expression"
[foregroundPoints addObject: @(point)];
Point *pointPtr;
// Fails with "Cannot initialise a parameter of type 'id _Nonull' with an lvalue of type 'Point *'"
[foregroundPoints addObject: pointPtr];
// Fails with "Cannot initialise a parameter of type 'id _Nonull' with an rvalue of type 'Point **'"
[foregroundPoints addObject: &pointPtr];
//Fails with: "Illegal type 'Point *' used in boxed expression"
[foregroundPoints addObject: @(pointPtr)];
What should I be doing to add the Point
to my NSMutableArray
?
(N.B. From the comments and some of the answers I see that I was confused about Point
. I'd assumed it was an Objective-C library class but in fact it was a C++ struct picked up from elsewhere in my project. So my question really boils down to this: how do I add a CGPoint
to an NSMutableArray
? I'll leave the main question unedited as the discussion in the comments and the answers that don't conflate Point
and CGPoint
are also interesting.)
Upvotes: 1
Views: 1986
Reputation: 35052
The issue is that only objects can be added to collections such as NSArray or NSDictionary.
Convert your "point" (likely a CGPoint or NSPoint struct) into an NSValue object that can be added to the array.
Use this class to work with such data types in collections (such as NSArray and NSSet), key-value coding, and other APIs that require Objective-C objects.
For example, use + valueWithCGPoint:
to convert the point to an NSValue representation that can be added to the array.
CGPoint point;
NSValue *pointValue = [NSValue valueWithCGPoint:point];
[foregroundPoints addObject:pointValue];
Then, later, use - CGPointValue
to convert the object back to the original type.
Upvotes: 3
Reputation: 2737
@pkamb answer is the way.
However, if you need performance, use a standard C array to store your points rather than do multiple calls to valueWithCGPoint and CGPointValue.
Embed it in a NSObject ( named PointArray, for example ) to do the manipulation.
@interface PointArray : NSObject
-(Point)pointAtIndex:(NSUInteger)index;
-(void)addPoint:(Point)point;
…
@property(nonatomic,readonly) NSUInteger numberOfPoints;
@end
@implementation PointArray
{
Point *points;
NSUInteger numberOfPoints;
}
// You'll have to work a bit there ..
@end
Upvotes: 1
Reputation: 12782
As others noted NSArray only holds Objective-C objects. To hold C types you need to box them in objects.
You need to use NSValue or NSString here. NSValue has boxing methods for most common Foundation structs and primitives.
There are also functions that also convert to and from NSString for several of these. See the Foundation Functions Reference.
Scalar C types can be boxed and unboxed using the NSValue subclass NSNumber
nil has to be represented using NSNull
Upvotes: 3
Reputation: 8924
You are trying to initialise NSMutableArray object with NSArray.
why don't you try this...
foregroundPoints = [NSMutableArray arrayWithObjects: @(startPoint), @(endPoint), nil];
Initialise NSMutableArray foregroundPoints to NSMutableArray not with NSArray.
Upvotes: 0