Objective-C class not recognized - objective-c

I'm new to Objective-C and I'm trying to use the UIImage+Resize class to resize a picture in iOS. See UIIimage+Resize.m code.
The resizeImage class is not recognized by XCode in the following code.
Error message: "Class method resizedImage:interpolationQuality not
found..."
#import "UIImage+Resize.h"
- (void)useImage:(UIImage*)theImage {
...
...
...
CGSize newSize = CGSizeMake (newWidth, newHeight);
CGInterpolationQuality InterpQual = kCGInterpolationHigh;
UIImage* newImg = [UIImage resizedImage:newSize interpolationQuality:InterpQual];
...
...
...
}

You are calling that method as if it was a class method ([UIImage ...]) however it's an instance method (note the leading -). So you need an instance of UIImage to call it on instead.

create an instance of UIImage before calling resize methode

Related

Objective-c convert a parent class to its derived class

I have a custom class named MyImage inherit from UIImage. Now I have a UIImage object, is there any ways to convert it into a MyImage object?
Update
Sorry for being unclear.
I cannot use a category because I need to add new properties to my class.
What I want to accomplish is to just let my MyImage object point to the original UIImage object.
Update 2
I tried something like this:
- (MyImage*)initWithUIImage:(UIImage *)image {
if (self = [super init]) {
self = image;
}
return self;
}
Obvious it does not work.
Also, since UIImage does not have a method named 'initWithImage:(UIImage*)', I cannot write something like
myImage = [[MyImage alloc] initWithImage:uiImage];
I also tried
self = [image copy]
But the return value is still a UIImage object, not a MyImage object.
Update 3
In MyImage, I need to add 3 properties: url, width, and height. Since I am writing a instant messaging app, and when receiving a new image message, I only have its url, width, and height. Then I assign those to a MyImage object, and download the image in the background.
Now given an original UIImage A, I want to create a new MyImage object B, which points to the same image as A, but with those new properties unassigned. Then I manually assign url, width, and height to B.
to #rmaddy, could you tell me how to write the method
[[MyImage alloc] initWithImage:(UIImage*)]
?
One way I can come up is first convert the UIImage object to NSData, then use
[MyImage imageWithData:]
Is there a better way?
I do not necessarily recommend this as a solution, but there is indeed a way to do exactly what you are looking for. It is called ISA Swizzling. Think of it like method swizzling but for Classes instead of methods.
Take a look at the Objective-C runtime's object_setClass [link]
I won't go into it (there are better resources out there), but this is essentially how KVO works. Regardless, it would be helpful if you better described the functionality of your UIImage subclass, so that we could help describe why a custom initializer as rmaddy describes is probably the best solution.
Your MyImage class is a subclass of UIImage, so if you're creating a new instance you need to properly initialize the superclass as well. UIImage doesn't provide a method to do that from another UIImage instance, but you can use a CGImage, and you can get one of those from the existing image. So do this:
- (MyImage*)initWithUIImage:(UIImage *)image {
if (self = [super initWithCGImage:image.CGImage]) {
// put any necessary MyImage-specific stuff here
}
return self;
}

Calling Obj-C Methods

I want to call a method B using a different method A. The problem is that the aksed parameters of method B is not present in Method A.
 
here's what I've tried ..
-(void) methodA {
// some code
CGSize *size = [CGSizeMake(self.frame.size.width, self.frame.size.height)];
[self methodB:size];
}
-(void) methodB:(CGSize) size {
//some code
}
There is certainly a better way...
Thanks
I don't think your code will be compiled.
CGSize is not an object.
Refactor to:
CGSize size = CGSizeMake(self.frame.size.width, self.frame.size.height);
[self methodB:size];
You should only wrap [] around methods. CGSizeMake(self.frame.size.width, self.frame.size.height) is a function, not a method, so get rid of the square braces. You can tell it's a function because functions look like functionName(argument1, argument2, ...) whereas methods look like [object methodName:argument1 methondNameContinued:argument2].
Further, CGSizeMake returns a CGSize structure, not a pointer to a CGSize structure, so ditch the * in *size.
Then you'll be left with this:
CGSize size = CGSizeMake(self.frame.size.width, self.frame.size.height);
[self methodB:size];
Which is correct.

Nil object reference in objective C

I am calling a class method from an outside class in order to obtain an object reference, in this case a reference to a UIImage. I can successfully call it and get it back from within myOtherClass itself, but when I call the method from myClass, it always returns nil.
#implementation myClass
...
- (UIImage *) gethThumb: (UIImage *) originalImage {
// always comes back nil:
UIImage* thumb = [MyOtherClass makeThumb: originalImage];
return thumb;
}
...
#end
#implementation MyOtherClass
...
+ (UIImage*) makeThumb: (UIImage *) fullImage {
CGSize imageSize = [fullImage size];
int shortestEdge = MIN(imageSize.width, imageSize.height);
CGRect rect = CGRectMake((imageSize.width - shortestEdge)/2, (imageSize.height - shortestEdge)/2, shortestEdge, shortestEdge);
CGImageRef imageRef = CGImageCreateWithImageInRect([fullImage CGImage], rect);
UIImage *thumb = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGSize thumbsize = CGSizeMake(180, 180);
UIGraphicsBeginImageContext(thumbsize);
[thumb drawInRect:CGRectMake(0, 0, thumbsize.width, thumbsize.height)];
UIImage *scaledThumb = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//scaledThumb is not nil here:
return scaledThumb;
}
...
#end
I stepped through and watched the value, I could see it was pointing to a valid memory address while still inside the makeThumb method, but once it had returned the pointer to the external class, the memory address was suddenly 0.
I tried writing it as an instance method and instantiating an object and then calling the method using
thumb = [self.myInstanceOfOtherClass makeThumb: originalImage];
and also changing the method to accept an object reference:
UIImage *thumbRef = nil;
thumb = [self.myInstanceOfOtherClass makeThumb: originalImage thumbRef:thumbRef];
-- in the myOtherClasss:
- (UIImage*) makeThumb: (UIImage *) fullImage thumbRef:(UIImage *) thumbRef {
...
thumbRef = scaledThumb;
...
}
... which I thought would prevent ARC from losing the reference to the object (if that's what's happening here).
I am relatively new to Objective C, and I'm hoping someone can explain to me why this is happening. Is the object being deallocated before it returns to the external class? Do I have to turn it into a property that is strong in the external class so the reference doesn't get discarded?
Forgot to mention: the reference is pointing to an image being created from a reference to a camera image in the UIImagePickerControllerDelegate method, didFinishPickingMediaWithInfo. The Camera UIView is dismissed before this thumb is created. I think maybe this is why I am losing the reference.
Thanks in advance for your help!!
You never allocated the memory for image. DO the following:
UIImage *myimage =[ [ UIImage alloc] init].

unrecognized selector sent to class CCAnimation

I am trying to get an Animation Helper with a cocos2d project and for some reason keep getting an error message:
unrecognized selector sent to class.
I have tried numerous approaches to no avail. I understand that it may have to do with a class-instance conflict, but I do not know how to resolve it. Any thoughts?
This is how I am calling the helper function:
CCAnimation* anim = [CCAnimation animationWithFrame:playerAnimName frameCount:1 delay:0.08f];
And this is the helper function itself:
+(CCAnimation*) animationWithFrame:(NSString*)frame frameCount:(int)frameCount delay:(float)delay
{
printf("start helper");
// load the players's animation frames as textures and create a sprite frame
NSMutableArray* frames = [NSMutableArray arrayWithCapacity:frameCount];
for (int i = 1; i < frameCount+1; i++)
{
NSString* file = [NSString stringWithFormat:#"%#%i.png", frame, i];
CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
[frameCache addSpriteFramesWithFile:#"maze-art.plist"];
CCSpriteFrame* frame = [frameCache spriteFrameByName:file];
[frames addObject:frame];
}
// return an animation object from all the sprite animation frames
return [CCAnimation animationWithSpriteFrames:frames delay:delay];
}
Any insight is appreciated. Thanks!
In order for category to work, you must define the new method in the following way. Please refer to this http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/chapters/occategories.html
#interface ClassName ( CategoryName )
// method declarations
#end
For example, your new method must be defined as
#interface CCAnimation (Helper)
+(CCAnimation*) animationWithFile:(NSString*)name frameCount:(int)frameCount delay:(float)delay
{
...
}
#end
Where do your helper method is? If it is inside your own class, that you have to call it as
[MyClass method];
not
[CCAnimation method];
+ means that method is static so you must call it with the class inside which this method is.

How can I correct this 'Incompatible Obj-c types' warning?

Specifically the warning is: "Incompatible Objective-C types 'struct NSString *', expected 'struct UIImage *' when passing argument 4 of 'objectWithType:name:code:image' from distinct Objective-C type". It follows a line that looks like so:
[Object objectWithType:#"Type" name:#"Name" code:#"0001" image:#"image.png"],
So, I understand that I created the class Object to take type UIImage, but I am providing it with type NSString. Here's the problem: I don't know how to indicate the image differently than its file name.
(Apologies if this is a basic problem. I'm new to this and trying to look for solutions before posting here. Any help you can offer is appreciated.)
You actually need an instance of UIImage, which you understand. So, the class method imageNamed: is typically used for this:
[Object objectWithType:#"Type" name:#"Name" code:#"0001" image:[UIImage imageNamed:#"image.png"]];
Another option (since you are using all strings here) might be to rewrite your method so that it takes a name instead of an image and then create the image inside the method implementation. So you might define the method:
- (void)objectWithType:(NSString*)type name:(NSString*)name code:(NSString*)code imageName:(NSString*)imageName
{
UIImage* theImage = [UIImage imageNamed:imageName];
// do whatever
}
Use [UIImage imageNamed:]. Will only work for images that are part of your project.
[Object objectWithType:#"Type" name:#"Name" code:#"0001" image:[UIImage imageNamed:#"image.png"]]
If 'image.png' is included in your project bundle, then you can do this to pass a UIImage instead of an NSString:
[Object objectWithType:#"Type" name:#"Name" code:#"0001" image:[UIImage imageNamed:#"image.png"]];