EXC_BAD_ACCESS on NSString sizeWithFont - objective-c

I am not sure what is going on anymore. I have tried so many things to for me to figure out whats going on on this specific line of code that is causing a EXC_BAD_ACCESS.
I tried enabled NSZombies but it didn't help me any. Here is the code:
- (int)linesFromText:(NSString *)string withFont:(UIFont *)font andSize:(CGSize)size {
NSArray *splitString = [string componentsSeparatedByString:#" "];
NSMutableArray *allLines = [NSMutableArray array];
NSMutableString *line = [NSMutableString string];
NSString *word;
NSString *fakeLine;
for (int i = 0; i < splitString.count; i++) {
word = [splitString objectAtIndex:i];
fakeLine = [NSString stringWithFormat:#"%#%# ",line, word];
//NSLog(#"line %#, font %#",fakeLine,font);
////THIS IS THE LINE CAUSING THE EXC_BAD_ACCESS
CGSize lineSize = [fakeLine sizeWithFont:font];
if (lineSize.width <= size.width) {
[line appendFormat:#"%# ", word];
} else {
[allLines addObject:[line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
line = [NSMutableString string];
[line appendFormat:#"%# ", word];
}
}
[allLines addObject:[line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
return allLines.count;
}
This is driving me crazy cause it only happens on the new iphone 5 when you scroll through the days to fast in the app I built. Here is a link to the application in the store:
http://itunes.apple.com/us/app/id543324451?mt=8
if you have an iphone 5 you can see what I mean. iphone 4 doesn't do this.
This code is being called in a UITableViewCell's layoutSubviews and is there to help size the frame of a Custom Attributed label that uses TTTAttributedLabel (https://github.com/mattt/TTTAttributedLabel).
I also tried to enable "Gaurd malloc to try give me more details but my XCode gives me this error:
dyld: could not load inserted library '/usr/lib/libgmalloc.dylib' because image not found
which if I look in /usr/lib that file is a sym link to a file that does exist in the same directory:
libgmalloc.dylib -> libgmalloc.B.dylib
I am running out of ideas here and thought it might be the UIFont getting released to soon and then it not being available so I put references in the UITableViewCell to hold the UIFont until the end of that Cell's life.
I have also searched around the internet and haven't found that much on this specifics.
Also here is an image of my stack trace from debugger:
http://i.stack.imgur.com/gWC5L.png
Any ideas?
Did I provide enough info?
Thanks

I think your question is answered here:
UIStringDrawing methods don't seem to be thread safe in iOS 6
The short version: sizeWithFont, and most other UIKit methods, are not thread safe when you're using it on the screen (rather than using it to pre-render).
The good news: look at Adam Swinden's answer in that thread; he explains how to get the same result in iOS6 with CoreText instead of UIKit.

Related

UIDocumentInteractionController weird behaviour on iphone with iOS7

I am hitting the wall with a problem for two days now and i would like your help. Before i start i should say that this problem is on iPhone 5 with iOS7 (I have also tested on iPhone 4 with iOS 6 and iPad 2 with iOS 7). This problem began when i tried to upgrade an application that has been on AppStore (iOS4 initially) and tried to make it iOS 7 compatible (supported on iOS6 onwards).
The scenario is pretty simple. I have a view with is a UIDocumentInteractionControllerDelegate. I download a file from a web service save it on the NSTemporaryDirectory and allow the user to Preview or Open In another app using the presentOptionsMenuFromRect. The code simplified is as follow:
I have declared a #property (nonatomic, strong) UIDocumentInteractionController *docController;
#autoreleasepool {
NSString *fileName = "uniquefilename"
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
fileURL = [NSURL fileURLWithPath:filePath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:filePath]){
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:"theurlofthefile"]];
NSError *writeError = nil;
[fileData writeToURL: fileURL options:0 error:&writeError];
if(writeError) {
//show error
}
}
docController = [UIDocumentInteractionController interactionControllerWithURL:url];
docController.delegate = self;
if (isIpad) {
[docController presentOptionsMenuFromRect:CGRectMake(location.x + 400,location.y, 100, 100) inView:tableView animated:YES];
}
else{
[docController presentOptionsMenuFromRect:CGRectZero inView:self.tabBarController.view animated:YES];
}
}
The problem is that i receive all kind of errors, i repeat the same process all the time and i get different errors, sometimes it works for many times in a row, sometimes it fails from the first go. The errors i receive amongst others which i will add when i get them again are:
* Terminating app due to uncaught exception 'NSGenericException', reason: '* Collection <__NSSetM: 0x16ff61e0> was mutated while
being enumerated.'
malloc: * error for object 0x177a56a4: incorrect checksum for
freed object - object was probably modified after being freed.
malloc: * error for object 0x1c2c8b50: double free * set a
breakpoint in malloc_error_break to debug
When the OptionsMenu is showed successfully i see "AirDrop: collectionView:layout:insetForSectionAtIndex:, orientation: 1, sectionInset: {0, 10, 0, 10}" in the console.
I tried enabling NSZombies and putting a breakpoint for malloc error but did not help me in any way.
Please help me or guide me to the right direction.
Thank you.
Bit late to answer, but hopefully it will help other people.
I had exactly the same issue when saving a file and presenting a UIDocumentInteractionController, it was absolutely random sometimes it would would perfectly 10 times in a row and sometimes it would crash on first try.
It seems to be caused by the file not having finished writing to disk, what fixed it for me was adding a delay before presenting the UIDocumentInteractionController to ensure that the file has finished writing to disk

NSZombiEnabled settings

I am trying to check NSZombieEnabled is working in my code.
I've the following settings :
and I've the following code in didFinishLaunchingWithOptions
NSString *string = nil;
[string release];
string = #"abc";
but, there is no error generated. there is no notification from NSZombie as well. Should I do some more settings. Please help me, cause I've a lib that I've imported and there is a EXC_BAD_ACCESS with code 13 happening, and I am not able to get to the error cause.
The stack and the console looks like this
Your settings are correct, but your code does not create any zombies. A zombie is an object which has been freed, but is re-used. Something like this will create a zombie:
NSString* string = [NSString stringWithString:#"abc"];
[string release];
[string length];
In this example, the string is released, and then you attempt to use it by calling its length method.
In the case of your library, what does the stack look like when it gives you the EXC_BAD_ACCESS?

Uploading Image to Dropbox

I'm trying to upload an image to dropbox. I'm using the latest version of the SDK (Sept. 17) and have successfully authenticated my app.
Here's the code that does it:
for ( NSUInteger i = 0; i < [photos count]; i ++ ) {
NSString *filename = [NSString stringWithFormat:#"%d.png", i+1];
NSString *file = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
[UIImagePNGRepresentation([photos objectAtIndex:i]) writeToFile:file atomically:YES];
NSString *destDir = #"/";
[self.dropboxClient uploadFile:filename toPath:destDir withParentRev:nil fromPath:file];
}
Note:
self.dropboxClient is an instanced DBRestClient object.
photos is an NSMutableArray of UIImages (I already checked to make sure that the objects are images using the NSStringFromClass() method on each object in the list);
Most importantly, I think there may be an issue with my DBRestClient object (self.dropboxClient), since none of the delegate methods are entered even though I've set the delegate.
Any and all help would be greatly appreciated!
This was a threading issue. DBRestClient methods, like createFolder and uploadFile:::: must be executed on the main thread.

Importing VCard in objective C in iPhone

I am developping an iPhone App using XCode 4.2 .in a portion of the App I will be getting a VCard as an NSString
I found this function initWithVCardRepresentation and i think it will be easier than parsing the data one by one (i.e getting the first name then the last name etc ... , but I have a hard time to implement it in my code .
I have the AddressBook and the AddressBookUI frameworks and I am trying to use this code but can t find an exact way to do it
-(IBAction)Add{
// I have a NSString *card defined somewhere else
ABAddressBookRef *iPhoneAddressBook = ABAddressBookCreate();
ABRecordRef *contact = ABPersonCreatePeopleInSourceWithVCardRepresentation(iPhoneAddressBook, (__bridge_retained CFStringRef) card);
CFRelease(contact);
CFRelease(iPhoneAddressBook);
}
when I compile ,it crashes at the line
ABRecordRef *contact = ABPersonCreatePeopleInSourceWithVCardRepresentation(iPhoneAddressBook, (__bridge_retained CFStringRef) card);
and I get the following green error in the #autoreleasepool
Thread1:Program Received Signal "SIGABRT".
I am quite new to the Apps development , please let me know if the information I gave is sufficient
Thanks
If you want to have an ABPerson afterwards (what is advisable), use:
// Assuming NSString *card exists already.
ABPerson *person = [[[ABPerson alloc] initWithVCardRepresentation:[card dataUsingEncoding:NSUTF8StringEncoding] autorelease];

AVAsset has no tracks or duration when created from an ALAsset URL

I'm pulling all of the video assets from ALAssetsLibrary (Basically everything that's being recorded from the native camera app). I am then running an enumeration on each video asset that does this to each video:
// The end of the enumeration is signaled by asset == nil.
if (alAsset) {
//Get the URL location of the video
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
NSURL *url = [representation url];
//Create an AVAsset from the given URL
NSDictionary *asset_options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
AVAsset *avAsset = [[AVURLAsset alloc] initWithURL:url options:asset_options];//[AVURLAsset URLAssetWithURL:url options:asset_options];
//Here is the problem
NSLog([NSString stringWithFormat:#"%i", [avAsset.tracks count]]);
NSLog([NSString stringWithFormat:#"%f", CMTimeGetSeconds(avAsset.duration)]);
}
NSLog is reporting that the AVAsset that I've gotten from my ALAsset has 0 tracks, and has a duration of 0.0 seconds. I checked the url, and it's "assets-library://asset/asset.MOV?id=9F482CF8-B4F6-40C2-A687-0D05F5F25529&ext=MOV" which seems correct. I know alAsset is actually a video, and the correct video, because I've displayed alAsset.thumbnail, and it's shown the correct thumbnail for the video.
All this leads me to believe there's something going wrong in the initialization for avAsset, but for the life of me, I can't figure out what's going wrong. Can anyone help me?
Update:
I think i've confirmed that the url being given to me by ALAssetRepresentation is faulty, which is weird because it gives me the correct thumbnail. I added this code in:
NSLog([NSString stringWithFormat:#"%i", [url checkResourceIsReachableAndReturnError:&error]]);
NSLog([NSString stringWithFormat:#"%#", error]);
It gives me this:
0
Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed. (Cocoa error 4.)" UserInfo=0x19df60 {}
I'm still not sure what would cause that. The only thing I'm noticing is the url, which is "assets-library://asset/asset.MOV?id=9F482CF8-B4F6-40C2-A687-0D05F5F25529&ext=MOV" is different from what I've seen as I've been searching around for this. The one i've seen elsewhere looks more like "assets-library://asset/asset.MOV?id=1000000394&ext=MOV", with a number instead of an alphanumeric, dash separated name.
If it helps, I'm using XCode 4.2 Beta, and iOS5. Please let me know if you can think of anything. Thanks.
Okay, looks like it was a bug in the iOS5 beta v1. I upgraded to the newest and it worked. Thanks to those who took a look at my question.