I have the 'classic' error:
unrecognized selector sent to instance.
If I read through other comparable questions it should be memory related, however I can't find out what I'm doing wrong.
Here is what I try to do:
crop an image
give the image rounded corners
I use the brilliant code of Trevor
This is my code:
The roundedCornerImage:borderSize: is giving the trouble
NSInteger my_borderSize = 0.1;
UIImage *Image_large = [image_sel croppedImage:CGRectMake((my_width/2) -(my_height*0.66)/2, 0, my_height*0.66, my_height) ];
UIImage *roundedCornerImage_temp = [Image_large roundedCornerImage:0.8 borderSize:my_borderSize];
That method is not in Apple's UIImage class. They are extensions to UIImage written by the guy whose code you link to.
You need to make sure to add UIImage+RoundedCorner.h and UIImage+RoundedCorner.m to your Xcode project, and then in the class where you want to use roundedCornerImage:borderSize:, you should
#import "UIImage+RoundedCorner.h"
Also, I notice that you're passing in decimal values for both cornerSize and borderSize. Those are supposed to be NSInteger values, per Trevor's API. I would guess that those are in display points, but apparently, he limited it to integer values.
Update: also make sure that the UIImage+RoundedCorner.m file is listed among your Compile Sources:
Related
FIXED: I'm not sure yet why. Code has been updated below, and notes at the bottom
I'm having a very strange error that does not show up on the Simulator (even when running Instruments), unless I turn on all the Zombie and Debug options. However, it will crash the phone after a minute of updates (1 update per second). I have a 2D array that I take a subset of, apply a colormap, and turn into an image (this array changes constantly). Then I pass that image to the model, and the viewcontroller grabs it from the model once it receives notification of an update. I'll layout the 3 classes -Spectrogram, Model, ViewController:
Here are the important bits of each (there is more, but not relevant):
Spectrogram.h (Sorry, I can't get this to indent correctly on here)
#interface: Spectrogram : NSObject
{
NSMutableData *arrayData;
}
//renamed so Xcode allows the object with +1 reference count to be returned
- (CGImageRef)newSpectrogramImage;
Spectrogram.m
#implementation Spectrogram
- (CGImageRef)newSpectrogramImage
{
//slightly reordered
NSMutableData *imageData = [[NSMutableData alloc] init];
...code to go through arrayData and colormap it (get RGB transform) and store in imageData...
CGImageRef arrayImage = nil;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//specifically tell CGImage there is no alpha channel
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone;
//Use the toll-free bridge between NSData and CFData
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)imageData);
arrayImage = CGImageCreate((slices-startSlice), bins, 8, 24, 3*(slices-startSlice), colorSpace, bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault); //image is rotated now, so width and height are switched
CGColorSpaceRelease(colorSpace);
CGDataProviderRelease(provider);
CGImageRelease(arrayImage);
[imageData release];
//Pass the CGImageRef with a reference count of 1
return arrayImage;
}
Model.h
#interface: Model : NSManagedObject
{
Spectrogram *spectrogram;
}
//Function the viewController can call to get the update
- (CGImageRef)newSpectrogramImage;
Model.m
#implementation Model
... there is a function that adds new data to the array and notifies all listeners...
- (CGImageRef)newSpectrogramImage {
return [spectrogram newSpectrogramImage];
}
ViewController.h
#interface: ViewController : UIViewController
{
}
//the root controller actually alloc's the record, and sets this property when creating this view
#property (nonatomic, retain) Record *currentRecord;
ViewController.m
#implementation ViewController
#synthesize spectrogramView;
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter ... listen for model updates...
}
//now, the real meat
- (void)recordUpdated:(NSNotification*)notification
{
CALayer *myLayer = self.view.layer;
CGImageRef spectrogramImage = nil;
spectrogramImage = [currentRecord newSpectrogramImage];
myLayer.contents = (id)spectrogramImage;
CGImageRelease(spectrogramImage);
}
I've changed this so many times in the last day trying to hunt down where and why it fails. I've tried passing the CGImageRef instead (but since that isn't an object, I'm worried about making copies of what can be a -huge- image) and it still fails. And it works perfectly in the simulator (will run for dozens of minutes). But fails within a minute on the iphone, or if I turn on the debug options for the simulator (it will fail as soon as the viewcontroller is loaded).
On a side note, that might be of some use. This viewcontroller is loaded as a modal view when the phone is turned sideways (works great). However, I have a lot of NSLogs in there and I see this viewcontroller's dealloc is called before the mainviewcontroller even gets to viewwilldisappear - but it still runs. And then this controller's dealloc is called again when the phone is turned back and the view disappears.
Note
The version that worked well in the simulator passed CGImageRefs all the way to the viewController, instead of UIImages. I've tried at least 50 different combinations of where to create the UIImage from the CGImage, and what's posted above is just one of them (all of them fail eventually, or immediately). Of note, with the code above, if I do add this to the viewController modelUpdated:
CGSize size = currentModel.spectrogramImage.size;
NSLog(#"width: %f", size.width);
and comment out assigning it to the spectrogramView, the width is reported correctly, so the UIImage is getting passed along, it's just not getting retained (This is how I understand the EXE_BAD_ACCESS error).
Also, recently I receive dan EXE_BAD_ACCESS on the
self.spectrogramImage = [spectrogram getSpectrogramImage];
line. So, I think the error may be inside the Spectrogram class. Even though the CGImage and UIImage code was taken from Apple examples.
Fixed notes
I read that setting the contents of the CALayer was a much quicker way to pass a CGImageRef to a view - and no UIImage intermediary. Unfortunately, I only commit working changes, so I can't see every iteration I went through. However, I know that I had something very similar to this several times that kept crashing. The problem was always that as it is currently written, the program would crash with EXE_BAD_ACCESS. And if I upped the reference count (or didn't release it), then it would work perfectly, but the object would leak. I still don't understand how that is possible. To have the difference between a leak, and a BAD ACCESS be a reference count of 1 (and not 2 or more).
I can't answer your specific question, but this might help you know what is going on a little bit better. I have a function "logMemUsage" that outputs your memory usage and shows how much it changed since last time. If you call it once a second or so, you can better understand how memory is being used in your app. If it keeps growing, obviously there's a leak, if it goes up and down as you expect it, that's good, if it doesn't go down when you think it should, you'll see it. It's in github here in Utilities.h/.m
It's hard to figure this out from what you've posted, but why not use properties with retain on all your allocated data? For example, you're returning an autoreleased UIImage from getSpectrogramImage, and it gets stored into Model with the call self.spectrogramImage = [spectrogram getSpectrogramImage];, but there isn't a property for spectrogramImage anywhere I can see, even though you're using the self. mechanism. Is it just that you didn't bother to post it? The way it's written it could be getting autoreleased, and then when you try to use it...
I'm trying to implement openFlow in my project but I cant seem to get the images to show up on my uiview. What isnt clear to me is once I have the dictionary of image links, how do i tell AFOpenView that I want to use that dictionary object as my data source?
I've looked at the demo code and I see that when the flickr request finishes, he saves a copy of the dictionary results, counts them, and then tells OpenFlowView that there are x number of images, but what is never clear is how he tells OpenFlowView to use the dictionary with the results?
- (void)flickrAPIRequest:(OFFlickrAPIRequest *)inRequest didCompleteWithResponse:(NSDictionary *)inResponseDictionary
{
// Hold onto the response dictionary.
interestingPhotosDictionary = [inResponseDictionary retain];
int numberOfImages = [[inResponseDictionary valueForKeyPath:#"photos.photo"] count];
[(AFOpenFlowView *)self.view setNumberOfImages:numberOfImages];
}
See here: http://blog.objectgraph.com/index.php/2010/04/09/how-to-add-coverflow-effect-on-your-iphone-app-openflow/
This tutorial seems to suggest that you have to call the view's setImage method multiple times, once per image.
This tells me that the implementation is confusing and weird, but for this you have to blame the component's author.
The images are loaded on demand in the 'updateCoverImage:' method of AFOpenFlowView.m
'updateCoverImage:' calls 'openFlowView:requestImageForIndex:' in AFOpenFlowViewController.m, which uses interestingPhotosDictionary.
So, it is called on demand whenever an image needs to be loaded. It wraps an operation queue so the images are loaded outside the main thread.
i have a question, totally newbie but i would like to know how can i get to compare and image in an if else statement?
i have an image lets say it is "img.png" and i have it displayed in an imageview already in the application, however in the codes i would like to compare if the image show is "img.png"
I understand that for string we use the isEqualToString:, so if it's for an image what would i use?
example would be :
if ([img.image isEqual:#"img.png"])
What i've typed is something like this but it isnt working. could anyone point me in the right direction? thanks alot
Much appreciated!
If you first got the image using [UIImage imageNamed:#"img.png"] you could compare the image object pointers: if (img.image == [UIImage imageNamed:#"img.png"]).
But: I'd consider this bad design and would rather use another way of identifying images, like storing the name of the image in another instance variable.
I am developing an image processing application by converting image to bitmap. I am manipulating bits in bitmap to get the desired effect.
First time i process an image it gives the correct result on the second try it gives
EXC_BAD_ACCESS
debugger is showing:
dataref outofscope
My code is
CGImageRef img=previewImageView.image.CGImage;
NSLog(#" Image : %# ", previewImageView);
CFDataRef dataref=CopyImagePixels(img);
CFDataRef dataref1=CopyImagePixels(img);
//UInt8 *data=(UInt8 *)CFDataGetBytePtr(dataref);
//UInt8 *original=(UInt8 *)CFDataGetBytePtr(dataref1);
UInt8 *data=nil;
data=(UInt8 *)CFDataGetBytePtr(dataref);
UInt8 *original=nil;
original=(UInt8 *)CFDataGetBytePtr(dataref1);
//original=data;
int length=CFDataGetLength(dataref);
Please help.........
A major cause of EXEC_BAD_ACCESS is from trying to access release objects.
To find out how to troubleshoot this, read this document: DebuggingAutoReleasePool
Even if you don't think you are "releasing auto-released objects", this will apply to you.
This method works extremely well.
In summary, this explains how to use Cocoa's NSZombie debugging class and the command line "malloc_history" tool to find exactly what released object has been accessed in you code.
It is useful to set a breakpoint on objc_exception_throw. That way the debugger should break when you get the EXC_BAD_ACCESS.
Instructions can be found here http://www.cocoadev.com/index.pl?DebuggingTechniques
http://img89.imageshack.us/img89/2554/screenshot20090910at154.png http://img89.imageshack.us/img89/2554/screenshot20090910at154.png
Full Size Image
Here you can see the code for the transition but it says there is an error before the "for"
What is it that i'm missing?
I basically want to do a fade in between images.
EDIT
Here is the updated code with the adjustments. I am still getting that error.
http://img186.imageshack.us/img186/7978/screenshot20090910at102.png http://img186.imageshack.us/img186/7978/screenshot20090910at102.png
Updated Code
The *NSArray** theImages line ends with the following
[UIImage imageNamed:#"image10.jpg"], [UIImage imageNamed:#"image11.jpg"], nil]];
The line before the for should read something like:
NSArray* theImages = [NSArray arrayWithObjects:[...], // object 1
..., // more objects
[...], // object N
nil]]; // nil must be last
Updated:
The error you are getting now is not the same as the one before. You'll need to look at more of your code in order to figure out what the error is referring to.
Also, can you post some of the code directly in your question instead of posting a picture? The font SO uses is easier to read than the one in the screenshots.
I don't know what language it is, but I beleave this line should end with ]; instead of ,
Your issues seem to be simple syntactical ones.
There is one caused by these two lines (can't see above it to see where the issue is
}
{
Also, you have a new issue with the NSArray* Definition because you have
NSArray* theImages]; = .....
^^This will cause an issue after you take care of the first one