Assigning to GLfloat from incompatible type void - calloc

This is driving me mad. I had to GLfloat with the next assignation in the implementation of a CCNODE class that simulates watter in side view (it comes from a Class that I found in cocos2dForum)
UPDATED:
-(id)initWithBounds:(CGRect)bounds count:(int)count damping:(float)damping diffusion:(float)diffusion;
{
if((self = [super init])){
_bounds = bounds;
_count = count;
_damping = damping;
_diffusion = diffusion;
_color = ccc4f(1.0f, 1.0f, 1.0f, 1.0f);
_h1 = calloc(_count, sizeof(float));//Here
_h2 = calloc(_count, sizeof(float));// And here, is where I get the error.
WaterTexture = [[CCTextureCache sharedTextureCache] addImage:#"watter.png"];
//shader_ = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_Position_uColor];
shader_ = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTexture];
_textureLocation = glGetUniformLocation(shader_->_program, "u_texture");
texturesize= 256*CC_CONTENT_SCALE_FACTOR();
offset=0;
}
return self;
}
- (void)dealloc
{
free(_h1);
free(_h2);
[super dealloc];
}
This class is implemented in a Cocos3d Project. Before add the Box2d library, all was working fine,the water was simulated, but after add the Box2D library, XCode begin to complain saying "Asigning to GLfloat from incompatible type void"
Why is this happening? It is really rare...
Regards.
Carlos.

I assume _h1 is of type CGFloat* or CGFloat[] - if it is not a pointer type then that's one issue. The other thing is that calloc returns void* so you need to cast its return value:
_h1 = (CGFloat*)calloc(..);
That the error occurs after adding Box2D is most likely due to the Objective-C++ behaving differently than the Objective-C compiler, apparently it does not perform an implicit cast in this case, requiring you to manually add the cast. Perhaps though the compiler already warned you about it, but now it's regarded as an error (hence the advice: never ignore warnings!).

Related

trouble with NSFastEnumeration protocol and ARC

I'm having trouble implementing the NSFastEnumeration protocol while migrating Objective-C code to ARC.
Could someone tell me, how to get rid of the following warnig (see code snippet)? Thanks in advance.
// I changed it due to ARC, was before
// - (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*) state objects: (id*) stackbuf count: (NSUInteger) len
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*) state objects: (__unsafe_unretained id *) stackbuf count: (NSUInteger) len
{
...
*stackbuf = [[ZBarSymbol alloc] initWithSymbol: sym]; //Warning: Assigning retained object to unsafe_unretained variable; object will be released after assignment
...
}
- (id) initWithSymbol: (const zbar_symbol_t*) sym
{
if(self = [super init]) {
...
}
return(self);
}
With ARC, something has to hold a strong or autoreleasing reference to each object, otherwise it will be released (just as the warning says). Because stackbuf is __unsafe_unretained, it's not going to hang onto the ZBarSymbol for you.
If you create a temporary autoreleasing variable and stash your object there, it will live until the current autorelease pool is popped. You can then point stackbuf to it without complaint.
ZBarSymbol * __autoreleasing tmp = [[ZBarSymbol alloc] initWithSymbol: sym];
*stackbuf = tmp;

CTRunDraw() does implement correct behaviour

I am implementing a custom text layout algorithm on MAC OS X using CoreText. I have to partially render a portion of CTRun in different locations inside a custom NSView subclass object.
Here is my implementation of drawRect: method
- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
CGContextRef context =
(CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(context); {
[[NSColor whiteColor] set];
NSRectFill(dirtyRect);
CTFontRef font = CTFontCreateWithName(CFSTR("Menlo"), 20, &CGAffineTransformIdentity);
CFTypeRef values[] = {font};
CFStringRef keys[] = {kCTFontAttributeName};
CFDictionaryRef dictionary =
CFDictionaryCreate(NULL,
(const void **)&keys,
(const void **)&values,
sizeof(keys) / sizeof(keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFAttributedStringRef longString =
CFAttributedStringCreate(kCFAllocatorDefault, CFSTR("this_is_a_very_long_string_that_compromises_many_glyphs,we_wil_see_it:)"), dictionary);
CTLineRef lineRef = CTLineCreateWithAttributedString(longString);
CFArrayRef runsArray = CTLineGetGlyphRuns(lineRef);
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runsArray, 0);
CGAffineTransform textTransform = CGAffineTransformIdentity;
textTransform = CGAffineTransformScale(textTransform, 1.0, -1.0);
CGContextSetTextMatrix(context, textTransform);
CGAffineTransform sequenceTransform =
CGAffineTransformIdentity;
sequenceTransform = CGAffineTransformTranslate(sequenceTransform, 0, 23.2818);
CGPoint firstPoint = CGPointApplyAffineTransform(CGPointMake(0, 0), sequenceTransform);
CFRange firstRange = CFRangeMake(0, 24);
CGContextSetTextPosition(context, firstPoint.x, firstPoint.y);
CTRunDraw(run, context, firstRange);
CGPoint secondPoint = CGPointApplyAffineTransform(CGPointMake(0, 26.2812), sequenceTransform);
CFRange secondRange = CFRangeMake(24, 24);
CGContextSetTextPosition(context, secondPoint.x, secondPoint.y);
CTRunDraw(run, context, secondRange);
CGPoint thirdPoint = CGPointApplyAffineTransform(CGPointMake(0, 52.5625), sequenceTransform);
CFRange thirdRange = CFRangeMake(48, 23);
CGContextSetTextPosition(context, thirdPoint.x, thirdPoint.y);
CTRunDraw(run, context, thirdRange);
}
CGContextRestoreGState(context);
}
Here is the output of this code
https://docs.google.com/open?id=0B8df1OdxKw4FYkE5Z1d1VUZQYWs
The problem is CTRunDraw() method inserts blank spaces on the positions other than the range specified.
What i want is it should render the part of run at its correct position.
Here is the correct out put which i want.(The correct output is photoshop of original output).
https://docs.google.com/open?id=0B8df1OdxKw4FcFRnS0p1cFBfa28
Note: I am using flipped coordinate system in my custom NSView subclass.
- (BOOL)isFlipped {
return YES;
}
You're misusing CTRun here. A CTRun is a horizontal box containing laid-out glyphs. It doesn't really make sense to try to draw portions of it underneath one another (certainly such typesetting would be wrong in any even slightly complicated case). Why? Well, because there are situations where the glyphs that are chosen might differ if there was a line break at a given position (this can happen, for instance, with ligatures). Also, note that there is not necessarily a 1:1 mapping between characters and glyphs.
My guess is that you probably don’t need your own full custom typesetter (and trust me, writing one is complicated, so if you don’t need one, don’t write one). Instead, just use CTTypesetter and/or CTFramesetter to get the output you want.

has anyone seen "[StdMovieUISliderCell sliderType]: unrecognized selector sent to instance"

I am using QTMovieView and , sometimes, I get the following log and follow by an unknown selector exception. The program has options for users to set to show and hide controller of the QTMovieView. The SDK that the program is linking against is 10.7
"[StdMovieUISliderCell sliderType]: unrecognized selector sent to instance"
thanks for any help
This looks like a bug that was introduced in OS X Mountain Lion 10.8 (Edit: there are also reports on OS X 10.7, see comments below) . I guess that QTMovieView will get deprecated in one of the next major OS X releases. The best solution is to move to AV Foundation (AVPlayer and the corresponding AVPlayerLayer class). Apple has some documentation about playing back assets using this framework.
That said, if you can’t update to AV Foundation or you can’t turn off Auto Layout, you still can fix this issue by adding the missing methods dynamically during runtime to the StdMovieUISliderCell class. Make sure to add the Objective C runtime header file and to add the methods as early as possible (e.g. + (void)load in your application delegate). For App Store static analyzer rejection foo reasons, it’s also safe to add some simple encoding to the class name like rot13.
// Make sure that we have the right headers.
#import <objc/runtime.h>
// The selectors should be recognized by class_addMethod().
#interface NSObject (SliderCellBugFix)
- (NSSliderType)sliderType;
- (NSInteger)numberOfTickMarks;
#end
// Add C implementations of missing methods that we’ll add
// to the StdMovieUISliderCell class later.
static NSSliderType SliderType(id self, SEL _cmd)
{
return NSLinearSlider;
}
static NSInteger NumberOfTickMarks(id self, SEL _cmd)
{
return 0;
}
// rot13, just to be extra safe.
static NSString *ResolveName(NSString *aName)
{
const char *_string = [aName cStringUsingEncoding:NSASCIIStringEncoding];
NSUInteger stringLength = [aName length];
char newString[stringLength+1];
NSUInteger x;
for(x = 0; x < stringLength; x++)
{
unsigned int aCharacter = _string[x];
if( 0x40 < aCharacter && aCharacter < 0x5B ) // A - Z
newString[x] = (((aCharacter - 0x41) + 0x0D) % 0x1A) + 0x41;
else if( 0x60 < aCharacter && aCharacter < 0x7B ) // a-z
newString[x] = (((aCharacter - 0x61) + 0x0D) % 0x1A) + 0x61;
else // Not an alpha character
newString[x] = aCharacter;
}
newString[x] = '\0';
return [NSString stringWithCString:newString encoding:NSASCIIStringEncoding];
}
// Add both methods if they aren’t already there. This should makes this
// code safe, even if Apple decides to implement the methods later on.
+ (void)load
{
Class MovieSliderCell = NSClassFromString(ResolveName(#"FgqZbivrHVFyvqrePryy"));
if (!class_getInstanceMethod(MovieSliderCell, #selector(sliderType)))
{
const char *types = [[NSString stringWithFormat:#"%s%s%s",
#encode(NSSliderType), #encode(id), #encode(SEL)] UTF8String];
class_addMethod(MovieSliderCell, #selector(sliderType),
(IMP)SliderType, types);
}
if (!class_getInstanceMethod(MovieSliderCell, #selector(numberOfTickMarks)))
{
const char *types = [[NSString stringWithFormat: #"%s%s%s",
#encode(NSInteger), #encode(id), #encode(SEL)] UTF8String];
class_addMethod(MovieSliderCell, #selector(numberOfTickMarks),
(IMP)NumberOfTickMarks, types);
}
}
I made two assumptions while implementing both methods:
A movie view can only have a linear slider, not a circular one.
A movie view won’t have tick marks.
The latter could be a problem if your movie has chapters, but I don’t know how they are handled, because I don’t need or use them.
I had the same problem if I tried to use setMovie: with AutoLayout on. An update to Xcode 4.4.1 fixed the problem.
i know it's a fairly old post, but for others out there, i had the same problem, i've just deactivated the cocoa autolayout for the xib file containing the QTMovieView and it worked like it should have.
i'm currently working with xcode 4.5.2 under OSX 10.7.4
Fixed this issue by adding empty updateConstraintsForSubtreeIfNeeded method in QtMovieView subclass.

Deep copy of dictionaries gives Analyze error in Xcode 4.2

I have the following method in a NSDictionary category, to do a deep copy, which works fine.
I just upgraded from Xcode 4.1 to 4.2, and the Analyze function gives two analyzer warnings for this code, as indicated:
- (id)deepCopy;
{
id dict = [[NSMutableDictionary alloc] init];
id copy;
for (id key in self)
{
id object = [self objectForKey:key];
if ([object respondsToSelector:#selector(deepCopy)])
copy = [object deepCopy];
else
copy = [object copy];
[dict setObject:copy forKey:key];
// Both -deepCopy and -copy retain the object, and so does -setObject:forKey:, so need to -release:
[copy release]; // Xcode 4.2's Analyze says this is an incorrect decrement of the reference count?!
}
return dict; // Xcode 4.2's Analyze says this is a potential leak
}
Are these bugs in Xcode's analyzer, or are there changes I can make to avoid these warnings?
I'm not using ARC yet, though I am interested if there are additional changes needed to support ARC for this method.
Presumably, it is because deepCopy does not begin with the prefix copy.
So you may want to change to something like copyWithDeepCopiedValues (or something like that), and then see if the analyzer flags that.
Update
As Alexsander noted, you can use attributes to denote reference counting intent. This should (IMO) be the exception to the rule, and used rarely, if ever. Personally, I will not use attributes for objc methods because it is fragile.
The only attribute I have used so far has been consume, and every time I use these attributes has been in statically typed contexts (e.g. C functions and C++ functions and methods).
The reasons you should avoid attributes when possible:
1) Stick with conventions for the programmers' sake. The code is clearer and you do not need to refer to the documentation.
2) The approach is fragile. You can still introduce reference count imbalances, and attributes can be used to introduce build errors due to conflicts in attributes.
The following cases are all built with ARC enabled:
Case #1
#import <Foundation/Foundation.h>
#interface MONType : NSObject
- (NSString *)string __attribute__((objc_method_family(copy)));
#end
#implementation MONType
- (NSString *)string
{
NSMutableString * ret = [NSMutableString new];
[ret appendString:#"MONType"];
return ret;
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
id obj = nil;
if (random() % 2U) {
obj = [[NSAttributedString alloc] initWithString:#"NSAttributedString"];
}
else {
obj = [MONType new];
}
NSLog(#"Result: %#, %#", obj, [obj string]);
}
/* this tool's name is ARC, dump the leaks: */
system("leaks ARC");
return 0;
}
This program produces the following error: error: multiple methods named 'string' found with mismatched result, parameter type or attributes.
Great, the compiler's doing what it can to prevent these issues. What that means is that conflicts in attributes can introduce errors based on the translation. This is bad because when nontrivial codebases are combined and attributes conflict, you will have errors to correct and programs to update. This also means that simply including other libraries in translation units can break existing programs when attributes are used.
Case #2
Header.h
extern id NewObject(void);
Header.m
#import <Foundation/Foundation.h>
#import "Header.h"
#interface MONType : NSObject
- (NSString *)string __attribute__((objc_method_family(copy)));
#end
#implementation MONType
- (NSString *)string
{
NSMutableString * ret = [NSMutableString new];
[ret appendString:#"-[MONType string]"];
return ret;
}
#end
id NewObject(void) {
id obj = nil;
if (random() % 2U) {
obj = [[NSAttributedString alloc] initWithString:#"NSAttributedString"];
}
else {
obj = [MONType new];
}
return obj;
}
main.m
#import <Foundation/Foundation.h>
#import "Header.h"
int main (int argc, const char * argv[])
{
#autoreleasepool {
for (size_t idx = 0; idx < 8; ++idx) {
id obj = NewObject();
NSLog(#"Result: %#, %#", obj, [obj string]);
}
}
/* this tool's name is ARC, dump the leaks: */
system("leaks ARC");
return 0;
}
Ok. This is just bad. We've introduced leaks because the necessary information was not available in the translation unit. Here's the leaks report:
leaks Report Version: 2.0
Process 7778: 1230 nodes malloced for 210 KB
Process 7778: 4 leaks for 192 total leaked bytes.
Leak: 0x1005001f0 size=64 zone: DefaultMallocZone_0x100003000 __NSCFString ObjC CoreFoundation mutable non-inline: "-[MONType string]"
Leak: 0x100500320 size=64 zone: DefaultMallocZone_0x100003000 __NSCFString ObjC CoreFoundation mutable non-inline: "-[MONType string]"
Leak: 0x100500230 size=32 zone: DefaultMallocZone_0x100003000 has-length-byte: "-[MONType string]"
Leak: 0x100500390 size=32 zone: DefaultMallocZone_0x100003000 has-length-byte: "-[MONType string]"
note: the count may differ because we used random()
This means that because MONType is not visible to main(), the compiler bound the ARC properties to methods which were visible to the current TU (that is, string from declarations in Foundation, all of which follow convention). As a result, the compiler got it wrong and we were able to introduce leaks into our program.
Case 3
Using a similar approach, I was also able to introduce negative reference count imbalances (premature releases, or a messaged zombie).
note: Code not provided because Case #2 already illustrates how one can accomplish a reference count imbalance.
Conclusion
You can avoid all these problems and improve readability and maintainability by sticking with convention, rather than using attributes.
Bringing the conversation back to non-ARC code: Using attributes makes manual memory management more difficult for programmers' readability, and for the tools which are there to help you (e.g. compiler, static analysis). If the program is suitably complex such that the tools can't detect such errors, then you should reconsider your design, because it will be equally complex for you or somebody else to debug these issues.
Adding onto #Justin's answer, you can tell the compiler that -deepCopy returns a retained object by appending the NS_RETURNS_RETAINED attribute to the method's declaration like so:
- (id) deepCopy NS_RETURNED_RETAINED;
Alternatively, you can use explicitly control the method's "family" using the objc_method_family attribute like so:
- (id) deepCopy __attribute__((objc_method_family(copy)));
If you do this, the compiler will know that this method is in the copy family and returns a copied value.

Layer size/bounds during a core animation

I am working on a Mac app for Mac OS X 10.6+ and need to redraw the contents of a CAOpenGLLayer while an animation is occurring. I think I've read up on all the necessary parts, but it is just not working for me. I set up the animation as follows:
[CATransaction setAnimationDuration:SLIDE_DURATION];
CABasicAnimation *drawAnim = [CABasicAnimation animationWithKeyPath:#"drawIt"];
[drawAnim setFromValue:[NSNumber numberWithFloat:0]];
[drawAnim setToValue:[NSNumber numberWithFloat:1]];
[drawAnim setDuration:SLIDE_DURATION];
[chartView.chartViewLayer addAnimation:drawAnim forKey:#"drawIt"];
chartFrame.origin.x += controlFrame.size.width;
chartFrame.size.width -= controlFrame.size.width;
chartView.chartViewLayer.frame = CGRectMake(chartFrame.origin.x,
chartFrame.origin.y,
chartFrame.size.width,
chartFrame.size.height);
The drawIt property is a custom property whose only purpose is to be called to draw the layer during the successive animation frames. It order to get this to work, you have to add this to the chartViewLayer's class:
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:#"drawIt"])
{
return YES;
}
else
{
return [super needsDisplayForKey:key];
}
}
So this seems to all be working fine. However, I need to get the current (animated) size of the layer before drawing it. I've found various conflicting information on how to get this out of the presentation layer. Here is what I've tried when the layer's:
drawInCGLContext:(CGLContextObj)glContext
pixelFormat:(CGLPixelFormatObj)pixelFormat
forLayerTime:(CFTimeInterval)timeInterval
displayTime:(const CVTimeStamp *)timeStamp
method is called during the animation. I've tried getting the size using KVC, and by querying either the frame or the bounds.
CALayer *presentationLayer = [chartViewLayer presentationLayer];
//bounds.size.width = [[[chartViewLayer presentationLayer]
// valueForKeyPath:#"frame.size.width"] intValue];
//bounds.size.height = [[[chartViewLayer presentationLayer]
// valueForKeyPath:#"frame.size.height"] intValue];
//bounds.size = presentationLayer.bounds.size;
bounds.size = presentationLayer.frame.size;
NSLog(#"Size during animation: %f, %f", bounds.size.width, bounds.size.height);
In all cases, the returned value is the end result of the animation rather than the transitional values. My understanding is that using the presentationLayer should give the transitional values.
So is this just broken or am I missing some critical step? Thanks for any help.

Resources