dumbledad
dumbledad

Reputation: 17535

Adding objects to an NSMutableArray in Objective-C

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

Answers (4)

pkamb
pkamb

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.

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSValue_Class/

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

Moose
Moose

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

uchuugaka
uchuugaka

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

Mahendra
Mahendra

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

Related Questions