Im following Ray Wenderlich tutorial for instruments, but I don't know why the profiling is not showing the leaked object??
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString * sushiName = [_sushiTypes objectAtIndex:indexPath.row];
NSString * sushiString = [NSString stringWithFormat:#"%d: %#", indexPath.row, sushiName];
NSString * message = [NSString stringWithFormat:#"Last sushi: %#. Cur sushi: %#", _lastSushiSelected, sushiString];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Sushi Power!"
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[alertView show];
//_lastSushiSelected = sushiString; //el que jode, pues lo pone en string deallocada, por strinWithFormat que usa autorelease!
_lastSushiSelected = [sushiString retain];
//[alertView release];
}
Im using the code in the tutorial, and as you can see the alertView is leaking!
But I run it trough instruments leaks, and nothing appears! [also is very very very slow to acknowledge the stop button was pressed to stop the profiling!]
So what is missing??,
thanks a lot!
Frankly, I think it's a bug. Hopefully it'll be fixed soon (I'm using v4.1) but all is not lost. Under the Allocations instrument you can filter which types are displayed. In this image I've told it to show UIAlertView instances. After clicking in the UITableView a couple of times you can see it tells me that there are 2 instances living, which confirms that there is a leak.
Related
I am fairly new to jailbreak iOS development and had a question. I am trying to send a message between two processes(MobileSafari to SpringBoard) and am having a problem, the reciever function in SpringBoard is never called! So far in SpringBoard I have this:
-(void)applicationDidFinishLaunching:(id)arg1{
%orig(arg1);
//register for notifications
CPDistributedMessagingCenter *messagingCenter = [CPDistributedMessagingCenter centerNamed:#"com.magnusdevelopment.flow"];
[messagingCenter runServerOnCurrentThread];
[messagingCenter registerForMessageName:#"updateWallpaper" target:self selector:#selector(handleMessageNamed:withUserInfo:)];
[messagingCenter registerForMessageName:#"updateScalingMode" target:self selector:#selector(handleMessageNamed:withUserInfo:)];
[messagingCenter registerForMessageName:#"downloadWallpaper" target:self selector:#selector(handleMessageNamed:withUserInfo:)];
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"Yo!" message:#"registered" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[testAlert show];
}
}
%new
-(NSDictionary *)handleMessageNamed:(NSString *)name withUserInfo:(NSDictionary *)userInfo{
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"Yo!" message:#"2" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[testAlert show];
if([name isEqualToString:#"updateWallpaper"]){
//get info for wallpaper
NSString *wallpaperImagePath = [userInfo objectForKey:#"WALLPAPER_PATH"];
int option = [[userInfo objectForKey:#"OPTION"] intValue];
BOOL retValue = setWallpaperImage(wallpaperImagePath, option);
//return the dictionary
NSMutableDictionary *replyDict = [[NSMutableDictionary alloc] init];
[replyDict setObject:[NSString stringWithFormat:#"%hhd",retValue] forKey:#"RETURN_VALUE"];
return replyDict;
}else if([name isEqualToString:#"updateScalingMode"]){
//get info from dictionary
int option = [[userInfo objectForKey:#"OPTION"] intValue];
NSString *scalingMode = [userInfo objectForKey:#"SCALING_MODE"];
//set wallpaper scaling mode
setWallpaperScalingMode(scalingMode,option);
}//end if
return nil;
}//end method
and when a button is pressed in MobileSafari I call this code:
NSString *option = [NSString stringWithFormat:#"%i",wallpaperOption];
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys: wallpaperPath, #"WALLPAPER_PATH", option, #"OPTION", nil];
CPDistributedMessagingCenter *messagingCenter = [CPDistributedMessagingCenter centerNamed:#"com.magnusdevelopment.flow"];
[messagingCenter sendMessageAndReceiveReplyName:#"downloadWallpaper" userInfo:infoDict];
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"Yo!" message:#"sent" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[testAlert show];
I get the alert "registered" whenever SpringBoard starts up and then when I press the button I get the message "sent". The only thing that isn't called is the function handleMessageNamed:withUserInfo:
Why isn't this working?
Thanks!
Try darwin notifications https://developer.apple.com/library/mac/documentation/corefoundation/Reference/CFNotificationCenterRef/Reference/reference.html It's a public API, shouldn't be hard to find sample code.
If you look at this document entitled "Updating extensions for iOS 7, it looks there are problems using CPDistributedMessagingCenter on iOS 7, but Ryan Petrich has published a library that may help you work around them:
Inter-process communication
CPDistributedMessagingCenter, XPC and other IPC methods built on top
of bootstrap registered mach services don't work; you get deny lookup
in the Xcode console.
Workaround: rpetrich has built a workaround called RocketBootstrap: "One common way processes communicate with each other
on iOS and OS X is through a messaging system called mach ports. Each
port is a channel that can either receive or send messages. There is a
central registration system for these ports called bootstrap, where
ports can be registered and accessed by a service name assigned to
them. Recent versions of iOS restrict which names a process can
access—MobileMail, MobileSafari and App Store apps are only allowed to
access a very specific set of services that come with iOS.
RocketBootstrap adds a secondary lookup service that doesn't restrict
which processes can access which services."
EDIT: The error is with the data structures that are being used during PDF generation. I'll be able to debug it once I can get a copy of OSX that supports iOS7. Thanks for all the help everyone!
At work I have Mac dedicated to working on iOS 6 apps. So far it hasn't been possible to update to a newer version of OSX so my version of XCode can't be upgraded to support iOS7 naturally. So long story short I can't debug iOS7 apps, so I am not sure why the app is crashing.
I have a UIActionSheet. I used to be using one with those completion blocks but was trying to debug so I have stripped everything away to just the basic barebones and it still crashes when I click on the button.
UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send by Email", #"Send To...", #"Open In...", nil ];
[actionSheet showFromBarButtonItem:sender animated:YES];
That's just sitting on the end of a PDF generation method.
Any ideas? I've been researching this all afternoon and I haven't found any reason why it would stop working like this. I did try storing the action sheet as data in the view controller so the reference was being kept, but to no avail.
I am using ARC.
EDIT: I tried an UIAlertView with the same results. Maybe it's the PDF context ruining things somehow?
Thanks for all the help everyone.
EDIT: Big breakthrough in solving this one: When commenting out my PDF generation code that's before my action sheet/modal dialog/alert view, it opens without complaint. So it's some kind of hybrid issue, and I'll post the majority of my method here so everybody can see what's up:
-(void)shareTapped:(id)sender
{
if (actionSheet.isVisible)
return;
if (![MFMailComposeViewController canSendMail])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No mail setup" message:#"You must setup your email in the main settings app before you can share." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return;
}
for( NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows )
{
// should only get run once due to UI
Calculation* calc = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString *filename = [calc.name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *path = [[[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent:filename] stringByAppendingPathExtension:#"ipc"];
[[PPCalculation sharedInstance] openCalculation:path];
}
[[PPCalculation sharedInstance] calculate];
// let's generate the PDF here!
NSMutableData* pdfData = [[NSMutableData alloc] init];
UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil );
UIGraphicsBeginPDFPage();
// 200 lines of drawing commands here
UIGraphicsEndPDFContext();
// save to file
NSString* path;
for( NSIndexPath *indexPath in self.tableView.indexPathsForSelectedRows )
{
// should only get run once due to UI
Calculation* calc = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* filename = [calc.name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
path = [[[[self applicationDocumentsDirectory] path] stringByAppendingPathComponent:filename] stringByAppendingPathExtension:#"pdf"];
[[NSFileManager defaultManager] createFileAtPath:path
contents:pdfData
attributes:nil];
}
// ActionSheet, modal dialog, composer dialog, alert view, all of them crash when I try to put them here
UIActionSheet* sheet = [[UIActionSheet alloc] initWithTitle:#"Share" delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send By Email", nil];
[sheet showFromBarButtonItem:sender animated:YES];
}
Thanks again guys.
EDIT: It seems that, from my investigation and commenting things out line by line and sending them to the device over TestFlight that it's the internal data structures somehow not working properly, which is strange, as the rest of the app works fine. I probably will get a copy of Mountain Lion or something so I can debug this thing properly.
Try below code... May be it will help you...
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send by Email", #"Send To...", #"Open In...", nil];
//actionSheet.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
actionSheet.tag = ((UIButton*)sender).tag;
[actionSheet showFromRect:[(UIButton*)sender frame] inView:[(UIButton*)sender superview] animated:YES];
By sheer trial and error and commenting out code, I have narrowed it down to the PDF generation itself. Somewhere in the guts of the C++ data structures something is happening that is making iOS7 sad but the others fine. I've managed to convince the boss to order Mountain Lion so once that arrives I can build for iOS7 directly and debug it properly.
Try This it will help yo
your barbutton action method :
UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle:nil: delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Send by Email", #"Send To...", #"Open In...", nil ];
[actionSheet showInView:self.view];
In my app there's a UIWebView showing a web page. It sometimes displays errors in a UIAlertView that are really annoying. I would like to intercept this and show the errors in a more sophisticated way.
Is there a way where i can intercept the error message in a function and decide for myself what i want to do with it?
Thanks in advance!
This seems to do it:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext *ctx = [webView valueForKeyPath:#"documentView.webView.mainFrame.javaScriptContext"];
ctx[#"window"][#"alert"] = ^(JSValue *message) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"JavaScript Alert" message:[message toString] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
};
}
Note: only tested on iOS 8.
Got a problem with the new Twitter.framework that I haven't been able to find a solution for yet.
Here is my code:
if ([TWTweetComposeViewController canSendTweet]){
TWTweetComposeViewController *twitter = [[TWTweetComposeViewController alloc] init];
[twitter addImage:tweetImage];
[twitter setInitialText:initalString];
[twitter addURL:url];
twitter.completionHandler = ^(TWTweetComposeViewControllerResult result) {
if (result == TWTweetComposeViewControllerResultDone) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"Tweeted"
message:#"You successfully tweeted"
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
});
} else if (result == TWTweetComposeViewControllerResultCancelled) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"Twitter"
message:#"Tweet has been canceled"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
});
}
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissModalViewControllerAnimated:YES];
});
};
[self presentViewController:twitter animated:YES completion:nil];
[twitter release];
}
Seems to be the standard way of implementing this although I made the addition of queuing the UI stuff on the main thread. The addImage, setInitialText and addURL parameters are all good. In, fact this works most of the time. The problem I am having is that occasionally when the TWTweetComposeViewController is alloc'd init the app freezes and I can see "twitterd session interrupted, restarting... " in the console. The app will hang sometimes for only a few seconds but more often it will hang for unreasonable amount of time (20 - 30 secs or more), I will get numerous of these messages and then the twitter controller will finally slide up. Occasionally, as well, it will just hang and never come back.
Was wondering it anybody has see this problem before or has any ideas on a solution to this problem?
Thanks in advance.
I never add these problems with the twitter view controller. I used my code pasted in this post: https://stackoverflow.com/questions/9314308/can-twtweetcomposeviewcontroller-tweet-sheet-rotate-to-landscape
You can try it, just change it to "self" when you dismiss or present in modal view, as I'm using a different view controller.
Loaded a list of items on to the UITableview and was able to click and show an alert for the row selected . But however after saying "ok" on the alert and i reclick on the already selected row my code breaks down saying "Thread 1:Program received signal:EXC_BAD_ACCESS".please take a look at the code below.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *playerselected = [exercises objectAtIndex:indexPath.row];
NSString *video = [playerselected valueForKey:#"video"];
NSString *msg = [[NSString alloc] initWithFormat:#"You have selected %#", video];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Player selected"
message:msg
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[video release];
[msg release];
}
PLease suggest me what could be the issue here.
Don't release video.
When you retrieve a value from an NSDictionary you don't own it unless you explicitly retain it.
To be more specific, when you retrieve your string it is still owned by the dictionary. When you release it, you are releasing an object that you do not own, resulting in it being over-released. As a result it is deallocated, and when you next try to access it the memory is no longer valid and your app crashes.