Obj-C... "Incompatible types in initialization" error - objective-c

My code:
CGPoint *tp_1 = CGPointMake(160, 240);
gives an "Incompatible types in initialization" error... why is this??

CGPointMake returns a struct, not a pointer to a struct. So the correct code is:
CGPoint tp_1 = CGPointMake(160, 240);

Looks like CGPointMake isn't returning a pointer.

Related

How do I get the dimensions of QTMovie

I'm trying to get a QTMovie's height and width, but can't get it right.
Here's the code (using ARC):
// get the movie's dimensions
NSSize *sourceSize = (__bridge NSSize *)([[movie movieAttributes] valueForKey:#"QTMovieNaturalSizeAttribute"]);
NSLog(#"%#", sourceSize);
// the output seems OK:
// NSSize: {1920, 1040}
NSLog(#"%f x %f", sourceSize->width, sourceSize->height);
// here's the output:
// 0.000000 x 0.000000
What am I doing wrong here?
Thanks to H2CO3's comments I got this to work. This is where I went wrong:
[movie movieAttributes] returns an NSDictionary and valueForKey is KVC which does not return non-object values but instead wraps them.
So NSSize sourceSize = [[[movie movieAttributes] valueForKey:#"QTMovieNaturalSizeAttribute"] sizeValue] would be the correct way to retrieve the NSSize struct.
Also - as H2CO3's comment suggests - this was a stupid mistake. Getting started is hard :-)

Collection element of type 'CGSize' is not an Objective-C object

I'm trying a give a NSDictionary key value a CGSize, and XCode is giving me this error. My code:
NSArray *rows = #[
#{#"size" : (CGSize){self.view.bounds.size.width, 100}
}
];
Why am I getting an error here? If its impossible to store a CGSize in a dict, then what's an alternative approach?
EDIT:
now getting "Used type 'CGSize' (aka 'struct CGSize') where arithmetic, pointer, or vector type is required" error with this code:
NSDictionary *row = rows[#0];
CGSize rowSize = [row[#"size"] CGSizeValue] ? : (CGSize){self.view.bounds.size.width, 80};
CGSize is not an object. It's a C struct. If you need to store this in an obj-c collection the standard way is by wrapping it in NSValue, like so:
NSArray *rows = #[
#{#"size" : [NSValue valueWithCGSize:(CGSize){self.view.bounds.size.width, 100}]
}
];
Then later when you need to get the CGSize back, you just call the -CGSizeValue method, e.g.
CGSize size = [rows[0][#"size"] CGSizeValue];
Kevin's answer only works on iOS; for Mac OS X (Cocoa) do:
[NSValue valueWithSize:NSMakeSize(self.view.bounds.size.width, 100)];

Implicit declaration of 'distanceBetweenPoints' is invalid in C99

The following code:
CGFloat currentDistance = distanceBetweenPoints(firstTouch,secondTouch);
gives me this error: Implicit declaration of 'distanceBetweenPoints' is invalid in C99
firstTouch and secondTouch are CGPoints
CGPoint firstTouch = [tOne locationInView:[tOne view]];
CGPoint secondTouch = [tTwo locationInView:[tTwo view]];
How do I get rid of this error?
I suppose you're using a very old version of Cocos2D? I only know this method by the name of ccpDistance. See: http://learn-cocos2d.com/api-ref/latest/cocos2d-iphone/html/_c_g_point_extension_8h.html#a76b1b389db811d00e0a461df630d9a8e
Make sure you have:
#include "CGPointUtils.h"
somewhere in your source file before you try to call distanceBetweenPoints.

Nullable in objective c

Is there a way to make nullable struct in objective C like in C# you can use Nullable<T>?
I need a CGPoint to be null when there is no applicable value. I cannot allocate a random invalid value for this like (-5000, -5000) because all values are valid for this.
What if you define a CGPoint using CGPointMake(NAN, NAN) similar to CGRectNull? Surely with NAN's for coordinates, it's not still a valid point.
CGPoint is a struct and that has some different rules in objective-c than you might think. You should consider reading about structs in objective-c.
The way this is done most of the time is to wrap the struct in an object because that object can be set to null. NSValue will wrap a CGPoint.
NSValue * v = [NSValue valueWithPoint:CGPointMake(1,9)];
NSVAlue * vNull = [NSValue valueWithPointer:nil];
if([v objCType] == #encode(CGPoint)) printf("v is an CGPoint");
CGPoint is a enum, not an object. You can use CGPointZero, or you can wrap all of your points inside of NSValue, which are objects and can be nil.
There is also nothing stopping you creating your own struct based on CGPoint, similar to how C# 2 works.
struct NilableCGPoint { bool isNil; CGPoint point; }
Examples of use:
// No value (nil)
NilableCGPoint myNilablePoint.point = CGPointZero;
myPoint.isNil = YES;
// Value of (0,0)
NilableCGPoint myNilablePoint.point = CGPointZero;
myPoint.isNil = NO;
// Value of (100, 50)
NilableCGPoint myNilablePoint.point = CGPointMake(100, 50);
myPoint.isNil = NO;

Converting a CGPoint to NSValue

In CABasicAnimation.fromValue I want to convert a CGPoint to a "class" so I used NSValue valueWithPoint but in device mode or simulator one is not working...
need to use NSMakePoint or CGPointMake if in device or simulator.
There is a UIKit addition to NSValue that defines a function
+ (NSValue *)valueWithCGPoint:(CGPoint)point
See iPhone doc
#ashcatch 's answer is very helpful, but consider that those methods from addition copy values, when native NSValue methods store pointers! Here is my code checking it:
CGPoint point = CGPointMake(2, 4);
NSValue *val = [NSValue valueWithCGPoint:point];
point.x = 10;
CGPoint newPoint = [val CGPointValue];
here newPoint.x = 2; point.x = 10
CGPoint point = CGPointMake(2, 4);
NSValue *val = [NSValue valueWithPointer:&point];
point.x = 10;
CGPoint *newPoint = [val pointerValue];
here newPoint.x = 10; point.x = 10
In Swift, you can change a value like this:
var pointValueare = CGPointMake(30,30)
NSValue(CGPoint: pointValueare)
&(cgpoint) -> get a reference (address) to cgpoint
(NSPoint *)&(cgpoint) -> casts that reference to an NSPoint pointer
*(NSPoint )(cgpoint) -> dereferences that NSPoint pointer to return an NSPoint to make the return type happy
In Swift the static method is change to an initialiser method:
var pointValue = CGPointMake(10,10)
NSValue(CGPoint: pointValue)
If you are using a recent-ish version of Xcode (post 2015), you can adopt the modern Objective-C syntax for this. You just need to wrap your CGPoint in #():
CGPoint primitivePoint = CGPointMake(4, 6);
NSValue *wrappedPoint = #(primitivePoint);
Under the hood the compiler will call +[NSValue valueWithCGPoint:] for you.
https://developer.apple.com/library/archive/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html
Don't think of it as "converting" your point-- NSValue is a wrapper class that holds primitive structs like NSPoint. Anyway, here's the function you need. It's part of Cocoa, but not Cocoa Touch. You can add the entire function to your project, or just do the same conversion wherever you need it.
NSPoint NSPointFromCGPoint(CGPoint cgpoint) {
return (*(NSPoint *)&(cgpoint));
}