Weird problem with UInt8 in iPhone (EXC_BAD_ACCESS) - iphone

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

Related

UIImage unrecognized selector sent to instance

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:

Calling ALAssetReprsentation's metadata method several hundred times will fail

I am writing a tiny iPhone app to retrieve metadata, such as EXIF info, for all photos stored in the iPhone, and ran into a weird issue when calling the Assets Library Framework API. Basically, if I am calling ALAssetReprsentation's metadata method (http://developer.apple.com/library/ios/documentation/AssetsLibrary/Reference/ALAssetRepresentation_Class/Reference/Reference.html#//apple_ref/occ/instm/ALAssetRepresentation/metadata) for several hundred times (even for the same ALAssetReprsentation object), the API will report an error and return null instead of photo's metadata.
Here is the code to reproduce this issue:
ALAsset *photo = ... // fetch a photo asset via Assets Library Framework
int i = 0;
ALAssetRepresentation *representation = [photo defaultRepresentation];
NSDictionary *metadata;
while (i<600) {
i++;
metadata = [representation metadata];
NSLog(#"photo %d indexed %#", i, metadata);
}
Here is the output for the code above. In the beginning of the output, everything is okay, but after 500+ times, the metadata API will report error like "ImageIO: CGImageSourceCreateWithData data parameter is nil".
...
2011-12-29 21:46:17.106 MyApp[685:707] photo 578 indexed {
ColorModel = RGB;
DPIHeight = 72;
DPIWidth = 72;
...
}
...
ImageIO: <ERROR> CGImageSourceCreateWithData data parameter is nil
2011-12-29 21:46:17.151 MyApp[685:707] photo 579 indexed (null)
ImageIO: <ERROR> CGImageSourceCreateWithData data parameter is nil
2011-12-29 21:46:17.177 MyApp[685:707] photo 580 indexed (null)
I am testing in an iPhone 3GS with iOS 5.0.1. And I am developing with Xcode 4.2 with ARC (automatical reference counting) enabled. And I can only reproduce this issue when deploying the app to the iPhone 3GS device, but cannot reproduce this issue when using iOS simulator with the same code (at least I don't reproduce this issue after calling the API over 1800 times in iOS simulator).
Any help is appreciated. Thanks.
It is possible that you are running out of memory. The method [representation metadata] returns an autoreleased object and possibly creates more autoreleased objects when it executes. All these instances are added to the autorelease pool, waiting to be finally released (and their memory freed) when the ARP gets the chance to drain itself.
The problem is that this won't happen until your code returns control to the run loop. So for the duration of your loop, at least 600 large dictionaries (and possibly many more objects) end up being allocated and not deallocated. Depending on the size of these objects, memory usage can increase tremendously.
This is true whether you are using ARC or not.
To avoid this issue, try creating a fresh autorelease pool on every iteration of the loop. That way, the ARP gets drained on every iteration:
while (i<600) {
#autoreleasepool {
i++;
metadata = [representation metadata];
NSLog(#"photo %d indexed %#", i, metadata);
}
}
This is not necessarily the best solution from a performance perspective but at least it will tell you whether the problem is memory related.
PS: Your code doesn't make much sense at the moment. Why retrieve the metadata for the same asset 600 times in a row?
enter code hereMake sure you retain the ALAssetLibrary until you are finished access related assets. From Apple's docs:
The lifetimes of objects you get back from a library instance are tied
to the lifetime of the library instance.

GLKTextureLoader fails when loading a certain texture the first time, but succeeds the second time

I'm making an iPhone application with OpenGL ES 2.0 using the GLKit. I'm using GLKTextureLoader to load textures synchronously.
The problem is that for a certain texture, it fails to load it the first time. It gives this error:
The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)
For this error code, the apple documentation says the following:
GLKTextureLoaderErrorUncompressedTextureUpload
An uncompressed texture could not be uploaded.
Available in iOS 5.0 and later.
Declared in GLKTextureLoader.h.
(not very much).
Could I be trying to load the texture while the opengl context is in some busy state or something like that?
Notes:
Before getting to load this texture I load other textures and those work on the first try.
Also, the exact same texture file will load ok on the second try.
There should be enough free video memory as I have only a couple of textures loaded before this one.
The texture is an uncompressed PNG with alpha, but I also tried with TGA (24bit & 32bit) with no luck.
Any ideas are welcomed, thanks
EDIT:
More info:
the opengl context is shared between all my screens. I'm doing this to keep my shaders and textures loaded between screens.
the problem above happens when I go to my second screen. In the first screen I draw textured stuff with no problems (other textures though).
The problem above happens when I load my content (game entities) in the game world. Each entity tries to load the texture. I have a simple caching system that loads the texture only once and then returns the same id for all other entities. I'm loading the entities synchronously, in one method. The first entity fails to load the texture then comes the second and succeeds and then the third one gets the cached id.
I am calling the load entities method in viewDidAppear and I've tried to add a sleep for 2 seconds before I load any entities but nothing changed.
EDIT:
Texture loading code:
- (GLKTextureInfo *)loadTextureAtPath:(NSString*)path ofType:(NSString*)type withKey:(NSString *)key
{
GLKTextureInfo* tex;
tex = [self textureWithKey:key];
if (tex)
return tex;
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO],
GLKTextureLoaderOriginBottomLeft,
nil];
NSError * error;
NSString *bundlepath = [[NSBundle mainBundle] pathForResource:path ofType:type];
tex = [GLKTextureLoader textureWithContentsOfFile:bundlepath options:options error:&error];
if (tex == nil)
DLOG_LOCAL(#"Error loading texture: %#", [error localizedDescription]);
else
[textures setObject:tex forKey:key];
return tex;
}
I was also getting
The operation couldn’t be completed. (GLKTextureLoaderErrorDomain error 8.)
when loading a texture late in runtime while several previous textures had loaded successfully closer to launch. I was able to solve the problem by inserting the following line of code before the GLKTextureLoader call:
NSLog(#"GL Error = %u", glGetError());
Sure enough, GL was reporting an error, but it did not require me to address the error in order for GLKTextureLoader to work. Merely getting the GL Error was enough.
I got this when enabling textures before loading the texture. Simply moved glEnable(GL_TEXTURE) after the loading and the issue was gone.
Maybe you've resolved this, but are you using multiple contexts? maybe you should be loading your texture asynchronously with sharegroup.
so instead of using tex = [GLKTextureLoader textureWithContentsOfFile:bundlepath options:options error:&error];
use something like:
GLKTextureLoader *textureloader = [[GLKTextureLoader alloc] initWithSharegroup:self.eaglContext.sharegroup];
GLKTextureInfo *myTexture;
[textureloader textureWithCGImage:_currentForegroundImage.CGImage options:nil queue:nil completionHandler:^(GLKTextureInfo *textureInfo, NSError *error) {
myTexture = textureInfo;
if(error) {
// log stuff
}
// do something
}];
I had a similar problem. Is was caused by a texture that had width / height not power of 2. GLKTextureLoader failed on loading this and the following images. Checking glGetError() after each texture load revealed the troublemakers :-).
Ok, I'll try this one again as I ran into the error again. What appears to happen is that if there is some other glError that has not been processed, then you will have trouble with the texture loading on the first time.
Before you load that texture that fails, check for a glError and then track down where that error occurred. Or you can capture an opengl frame prior to where the texture is loaded and see if a glError is being thrown prior. This happened to me both times when I ran into the error 8, and both times this error disappeared once I fixed the error that had occurred earlier.
I ran into the same problem. I'm not exactly sure as to why it occurred exactly other than that it appeared that there were multiple file operations going on at the same time. For example, performing a file load (for model data) right AFTER using the texture loader for the first time would cause error 8 to pop up. I fixed it in my program by having some other operations occur after the texture loader is called for the first time.
I've also found that you get this error when trying to create a 2D texture with an image larger than the maximum texture size. For the max size you can see Apple's Open GL ES Platform Notes, although those do not appear correct for newer devices so the best bet is to get the value directly.
I had very similar problem and it has been solved by calling setCurrentContext.
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.context];

CGImage/UIImage passing causes EXE-BAD-ACCESS

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...

How to Load an array into OpenFlow

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.