NativeScript Core

Structures

You can pass object literals where a structure is expected:

typedef struct _NSRange {
    NSUInteger location;
    NSUInteger length;
} NSRange;

@interface NSMutableArray (NSExtendedMutableArray)
- (void)removeObjectsInRange:(NSRange)range;
@end
var array = NSMutableArray.arrayWithArray([1, 2, 3, 4]);
array.removeObjectsInRange({ location: 1, length: 2 });
console.log(array); // [1, 4]

For each structure there exists a constructor object with the name of the structure (or typedef). When marshalled from native, structure instances are exposed as wrapper objects, which manage the lifetime of their memory buffer.

var instance = new NSRange(); // Creates a structure with zeroed memory
console.log(instance.location); // 0
console.log(instance.length); // 0

You can also construct a wrapper from object literal. Not all fields are required.

var instance = new NSRange({ location: 3, length: 4 });
console.log(instance.location); // 3
console.log(instance.length); // 4

Constructing/Casting from Pointer

The struct constructor can be used to cast from Pointer to structure instance.

var size = interop.sizeof(NSRange);
var buffer = interop.alloc(size);

var struct1 = NSRange(buffer); // Does not create a copy
console.log(interop.handleof(struct1) === buffer); // true

var struct2 = new NSRange(buffer); // Creates a copy
console.log(interop.handleof(struct2) === buffer); // false

Testing for Equality

To check if two structures are equal you can use: <StructConstructor>.equals(a, b):

console.log({ location: 0, length: 3 } === { location: 0, length: 3 }); // false
console.log(NSRange.equals({ location: 0, length: 3 }, { location: 0, length: 3 })); // true

This method performs deep equality for nested structures.

toString and toJSON

To view the contents of the structure use JSON.stringify().

console.log(new NSRange().toString()); // "<struct NSRange: 0x7f9e1a497710>"
console.log(JSON.stringify(new NSRange())); // "{ location: 0, length: 0 }"

Nested Structures Gotchas

Be careful when working with nested structures:

struct CGPoint {
    CGFloat x;
    CGFloat y;
};

struct CGSize {
    CGFloat width;
    CGFloat height;
};

struct CGRect {
    CGPoint origin;
    CGSize size;
};
var rect = new CGRect();
rect.size.height = 3; // Doesn't work as expected
console.log(rect.size.height); // 0

A temporary CGSize is created and its height is set to 3. The size of the rect structure is still 0.

Limitations

  • Structures with arrays are not supported.