Objective-C
NSArray
CGPoint
iOS Development
Programming Tips

How can I add CGPoint objects to an NSArray the easy way?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

CGPoint is a C struct, while NSArray stores Objective-C objects. Because of that mismatch, points must be boxed before insertion into Objective-C collections. The standard approach is using NSValue, which safely wraps and unwraps Core Graphics structs. This pattern is stable, readable, and compatible with both legacy Objective-C APIs and mixed Swift projects.

Store CGPoint Values with NSValue

Use valueWithCGPoint: when adding points to mutable arrays.

objective-c
1#import <Foundation/Foundation.h>
2#import <CoreGraphics/CoreGraphics.h>
3
4NSMutableArray<NSValue *> *points = [NSMutableArray array];
5
6CGPoint p1 = CGPointMake(10.0, 20.0);
7CGPoint p2 = CGPointMake(30.5, 40.25);
8
9[points addObject:[NSValue valueWithCGPoint:p1]];
10[points addObject:[NSValue valueWithCGPoint:p2]];
11
12NSLog(@"count: %lu", (unsigned long)points.count);

This is the cleanest method for Objective-C APIs that need array storage.

Read Points Back Correctly

Unbox with CGPointValue before geometry operations.

objective-c
1for (NSValue *boxed in points) {
2    CGPoint p = [boxed CGPointValue];
3    NSLog(@"x=%.2f y=%.2f", p.x, p.y);
4}

Avoid pointer casts or manual memory tricks. NSValue handles layout correctly.

Use Typed Collections for Clarity

Modern Objective-C supports lightweight generics for readability:

objective-c
1NSArray<NSValue *> *pathPoints = @[
2    [NSValue valueWithCGPoint:CGPointMake(0, 0)],
3    [NSValue valueWithCGPoint:CGPointMake(50, 75)]
4];

This helps static analysis and makes intent clear during reviews.

Bridge with Swift Cleanly

Swift arrays can store CGPoint directly. When crossing Objective-C boundaries, convert explicitly.

swift
1let objcPoints: [NSValue] = [
2    NSValue(cgPoint: CGPoint(x: 1, y: 2)),
3    NSValue(cgPoint: CGPoint(x: 3, y: 4))
4]
5
6let swiftPoints: [CGPoint] = objcPoints.map { $0.cgPointValue }
7print(swiftPoints)

Keep boxing at boundaries so internal Swift logic can use value types directly.

Reusable Helper Functions

If your code frequently boxes points, helper functions reduce noise.

objective-c
1NSArray<NSValue *> *BoxCGPoints(const CGPoint *points, NSUInteger count) {
2    NSMutableArray<NSValue *> *result = [NSMutableArray arrayWithCapacity:count];
3    for (NSUInteger i = 0; i < count; i++) {
4        [result addObject:[NSValue valueWithCGPoint:points[i]]];
5    }
6    return result;
7}

Central helpers also reduce copy-paste bugs across rendering modules.

Performance Considerations

Boxing and unboxing has overhead. For performance-sensitive loops such as hit testing thousands of points per frame, prefer native buffers or Swift [CGPoint] internally, then box only when required by Objective-C APIs.

Good pattern:

  • compute with native point arrays,
  • convert to an NSValue array only at API boundary.

This balances speed and interoperability.

Validate Round-Trip Accuracy

Add quick tests for precision and order preservation.

objective-c
1CGPoint source = CGPointMake(12.5, -3.75);
2NSValue *boxed = [NSValue valueWithCGPoint:source];
3CGPoint restored = [boxed CGPointValue];
4
5BOOL same = CGPointEqualToPoint(source, restored);
6NSLog(@"round trip ok: %@", same ? @"YES" : @"NO");

Include negative and fractional coordinates in tests, especially for drawing and layout code.

Convenience Category for Cleaner Call Sites

If your project stores many geometric structs, a small category around NSValue improves readability and avoids accessor mistakes.

objective-c
1@interface NSValue (CGPointBoxing)
2+ (instancetype)mq_valueWithPoint:(CGPoint)p;
3- (CGPoint)mq_pointValue;
4@end

Using project-specific names can make code search easier and enforce consistent boxing conventions across modules.

Common Pitfalls

  • Trying to insert raw CGPoint structs directly into NSArray.
  • Using the wrong unboxing accessor for stored struct types.
  • Performing geometry math on boxed values without unboxing first.
  • Overusing boxed point arrays in tight rendering loops.
  • Mixing coordinate spaces without documenting expected input and output.

Summary

  • 'CGPoint must be boxed as NSValue for Objective-C array storage.'
  • Use valueWithCGPoint: and CGPointValue for safe conversion.
  • Keep boxing at API boundaries when working with Swift value arrays.
  • Add helpers and tests for clarity and reliability.
  • Prefer native point containers in performance-critical paths.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.