I have a UIButton that is linked to some code that invokes UIPrintInteractionController to print a PDF document.
If I tap the button, the view pops up to let me select a printer and then print the document. However, if I tap outside the view to dismiss the popup, and then quickly tap the "Print" button again, I get the following crash:
[NSConcreteData respondsToSelector:]: message sent to deallocated instance 0xa4696d0
I have debugged with NSZombies enabled, and the crash occurs at this line:
printController.printingItem = dataToPrint;
dataToPrint is instantiated in the same method but prior to this printController line:
NSData *dataToPrint = [NSData dataWithContentsOfFile:pdfFileName];
This crash only occurs if I tap quickly, if I give it a second, everything goes smoothly.
Anyone have any idea what this could be?
Make 'dataToPrint' a strong ivar, and only nil it when you are 100% sure it won't be used again. Most likely the 'printController.printingItem' retains it, but when you dismiss the popup it gets released before the 'Print' button is hit again.
Related
UPDATE:
Should have read the reference documentation...
"A reference to the place picker must be retained for the duration of the place picking operation. If the retain count of the place picker object becomes 0, the picking operation will be cancelled and the callback will not be invoked."
Make sure your placePicker object is referenced in your UITableViewController class:
GOOD: placePicker = GMSPlacePicker(config: config)
BAD: let placePicker = GMSPlacePicker(config: config)
Original Problem:
I have a UIButton element inside of a UITableViewCell in Storyboard connected by IBAction to a function in my UITableViewController.
The function executes when I press the button, and configures the GMSPlacePicker object as instructed in Google's SDK Guide (https://developers.google.com/places/ios-api/placepicker).
Upon calling the pickPlaceWithCallback function, it seems like the Place Picker UI comes up and then immediately closes, taking the user back to the UITableViewController. The callback doesn't run at all so there's no error being passed back to help debug.
Anyone run into this problem?
I tried to run this method of code
- (IBAction)signInButton:(id)sender {
NSLog(#"Run Action %#", #"Here");
}
The result of this code log the "Run Action Here" twice in the console.
I initially loaded all my project import file (.m and .h) in one header file "Loader.h", I taught this was the cause, but I still experience the same issue even after I dissembled the header file.
Same Issue happens on other view controller.
What am I doing wrong ?
Thanks in advance.
It sounds like you've connected the action to your button or other UI element for two different events. For example, if you connect it to both the touch down and touch up events, a single tap of the button will trigger the action twice.
One thing you can do to diagnose the problem is to control-click on the view controller containing the action in your nib or storyboard and look at the Received Actions section near the bottom of the resulting popup. You'll likely see your action connected twice.
Another option is to set a breakpoint in the action and take a look at the sender parameter each time you hit the breakpoint. This will show you what object is triggering the action each time.
This seems to be some problem with the logging. It indeed logs twice from IBAction handlers. I put NSAlert, to make sure it's called twice, but it was called once, nevertheless the log was printed twice in the console.
In my app I've a UITableView in which I have custom UITableViewCells and those cells contain UIWebView in which I am displaying YouTube video using <iframe>. When I click on a video and instantly scroll the table before a full screen player opens, the app crashes. I tried Instruments to find the problem and came to know that An Objective-C message was sent to a deallocated 'AAHomeNewsListCell' object (zombie) at address: 0x118e09800.

I'm using ARC and I can't find a way to resolve this issue.
You are sending a message to an object that is no longer alive. The best way to debug that problem would probably be to set a break point as close as you can to where the situation happens, and step through the code. A good place to start would be close to where you use an AAHomeNewsListCell-object, or close to where you trigger the full screen player.
If I had to guess, I'd say that the web view is messaging its delegate but the delegate has already been deallocated. UIWebViewDelegate comes with this handy warning:
Important: Before releasing an instance of UIWebView for which you have set a delegate, you must first set the UIWebView delegate property to nil before disposing of the UIWebView instance. This can be done, for example, in the dealloc method where you dispose of the UIWebView.
Looking at your zombie message, what is it that would be still trying to message the cell? Is your cell acting as the web view's delegate?
Edit Looking at what message is being sent, it gets _setFirstResponder:. It could be a text entry form in the web view that's trying to get first responder to enter text.
I receive the strangest error: whenever I press and hold a UIButton on my UIView (literally taken from the Storyboard IB and placed onto the screen with no additional edits whatsoever) I receive this error -[NSPlaceholderString initWithFormat:locale:arguments:]: nil argument'
Has this happened to any of you before?
p.s. it also only happens on this particular viewcontroller...
additional note: this ONLY happens when I press and hold the button. I can't for the life of me replicate the error anyway else...
How can I check when an instance of MPMoviePlayerController is deallocated? Note I already have NSZombieEnabled set to YES and checked.
The code in question works great under some circumstances in my app. In another, when the view with the moviePlayer controls is expanded, the MPMoviePlayerDidEnterFullscreenNotification callback method is executed and shortly after the screen goes black and the app from user viewpoint freezes. (The difference is this one has an extra viewController on the navigation stack). It does not crash the app. It is still running but can not return back to a usable UI.
In the debugger, I check the last known time when the instance was "alive" to get its address, to check and find it is deallocated:
2012-10-01 18:35:46.032 MyApp[930:907] -[MyMoviePlayerViewController moviePlayerDidEnterFullscreenNotification:](203): : moviePlayer = <MPMoviePlayerController: 0x1dba9420> loadState = 3
2012-10-01 18:36:05.280 MyApp[930:907] [MPAVController] Autoplay: Enabling autoplay
Black screen occurs here, so I check the debugger:
(lldb) po 0x1dba9420
2012-10-01 18:37:38.656 MyApp[930:907] *** -[MPMoviePlayerController respondsToSelector:]: message sent to deallocated instance 0x1dba9420
(int) $0 = 498766880 [no Objective-C description available]
If I check other known instance of other classes, they are alive and well as expected:
(lldb) po 0x1da12110
(int) $1 = 497099024 <MyDetailViewControllerWithTableView: 0x1da12110>
(lldb) po 0x1da1af70
(int) $2 = 497135472 <MyMasterTableViewController: 0x1da1af70>
(lldb) po 0x1da19be0
(int) $3 = 497130464 <NSFetchedResultsController: 0x1da19be0>
So, to reiterate, how does one check when and by what an instance gets deallocated or destroyed? Is there an Instruments type that can be used.
Allocations shows that instances was allocated and now not alive....
I suppose I can do a fine step by step trace but that is tedious...
Would be great to be able to set a condition when the event occurs and trigger
the Instruments (or debugger) to stop.
I fixed this. It appears that when the user expands the moviePlayer, the event lifecycle causes the view (MyAddDetailViewController) (that holds the subview (MyMoviePlayerController)) to execute viewWillDisappear & viewDidDisappear.
I mentioned that the code path created an additional viewController on the navigation stack, and that VC was making a brief appearance (evidenced by a viewWillAppear message) then going back into the background with viewWillDisappear. It still is not clear why that would cause the autoreleasePool to free up MyAddDetailViewController thus deallocating MyMoviePlayerController, but it is now clear that there was no strong reference to MyAddDetailViewController.
To fix, I created a property in the VC that pushes MyAddDetailViewController onto the navigation Stack to hold a strong reference to it.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// ... snip ...
self.myAddDetailViewControllerReference = [segue destinationViewController];
}
//
- (void)viewDidUnload {
[self setMediaAddDetailViewControllerReference:nil];
}
That takes care of the black screen/freeze.