I get a crash in WebEditorClient::clearUndoRedoOperations which is trying to access -[WebView(WebViewEditing) undoManager] when I close the main window of an NSDocument that contains a webview with a text editor in it. It only happens when there is an undo-able state. Seems like a bug in Cocoa, but I might be doing something wrong. Any ides why this might be going on? The web view is in a nib and not created programmatically, so I'm not sure what I can do to even begin fixing this.
Well, removing it from superview prior to calling close on the document seems to have fixed it. Still, that doesn't explain what was going on, but just putting it here in case other people have this problem.
Related
G'day!
Note: Minimal example linked below. I'll refrain from longish code excerpts and rather explain the problem concisely.
I am in the process of updating an old (but small) Cocoa application to current APIs.
One of the places that looked easy enough at first: When the user tries to close the application window with unsaved changes, the app first displays an NSAlert asking "Save your stuff?". If that is confirmed a modal NSSavePanel is shown. In the original code they were opened via, respectively:
beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:
beginSheetForDirectory:file:modalForWindow:modalDelegate:didEndSelector:contextInfo:
Current Cocoa API uses completion blocks and thus the alert prefers to be shown via beginSheetModalForWindow:completionHandler:. So I moved the code from the didEndSelector into the completionHandler.
Unfortunately the modal NSSavePanel does animate in but disappears immediately together with the application main window if it is shown from the NSAlert's completion block. If I switch the alert back to the didEndSelector I can show the NSSavePanel either selector-basedly or completion block-ly just fine.
Here's the NSAlert's completion block that forwards to the disappearing save panel.
I have thought about threading issues. All of this is happening on the main thread. Maybe there's something subtle going on with run loop modes that I'm missing?
The minimal example is available over on GitHub. You can switch between selectors and blocks with defines in AppDelegate.h. All the interesting code is in AppDelegate.m. (Unless the problem is somewhere else...)
As #Willeke pointed out this wasn't an overly mysterious issue with threading and whatnot. No. It was just me having looked at the code way too often over the course of days.
The solution is simple:
The breaks in the switch statement in confirmUnsavedChanges are missing.
I'm looking for a simple way of adding a refresh mechanism to my UIWebView. I've seen posts about the EGO pull to refresh but, to be honest, I don't understand how that works, especially since I have no clue on how to use it with a UIWebView instead of a table view. And it seems to me like a lot of overhead for just a simple refresh.
I thought about adding a navbar but instead of a back button, add a custom "refresh" one. But based on what I've found so far, it seems as complicated as the other solution.
So, basically, I'd like to know what you would do. Keep in mind that the only requirement is that the user have some easy way of refreshing the view. Any suggestion ?
*I'm a begginer in Objective-C so that is why I don't understand how to plug the EGO framework with a UIWebView even after downloading and running the code.
Well,
Create a button and inside button's IBAction,
- (IBAction) performReload:(id) sender {
[self.uiwebview reload];
}
Check the documentation, it will help you a lot at your beginning stage.
Visual Suggestion:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebView_Class/Reference/Reference.html
I managed to create a bug where a cocoa program is exiting.
-[NSApplication terminate:] is apparently not called.
Nor is -[NSException init].
There is no crash. What I am seeing in gdb is that exit() is being called directly from NSApplicationMain without going through the normal [NSApplication terminate] path.
Any ideas about how to debug this and/or how this (seemingly "impossible" behavior) could happen?
Thanks in advance from a cocoa newb.
I would start with judicious use of breakpoints. Narrow it down to the last place where your code is seen before the faux crash and then start looking around that area for memory issues. Whenever I have really strange behavior, it's almost entirely due to a strange memory bug.
There are few remaining routes that would cause your application to voluntarily exit without going through the normal [NSApplication terminate] path.
Try setting a breakpoint on "stop:". I suspect somehow, perhaps an inappropriately named performSelector call? Or a badly named IB connection, you are calling this method, which is documented to exit from the main event loop.
After mulling this over I guessed that I was doing something wrong "in the big picture". So, "in the big picture", what I was doing is calling a modal dialog (by loading a window nib, showing the window and then using [NSApplication beginModalSessionForWindow]...[NSApp runModalSession]... and upon close [NSApp endModalSession]. This has worked for me in other chunks of code no big deal. The critical difference was that this modal window was being loaded and run out of another class's awakeFromNib.
I wrote a simple app that will reproduce this behavior. So what happens is that the modal dialog loads happily and when you close the modal window not only does it close but the app exits. I imagine that this is an "as designed" behavior. I was reading up in apple docs to see if I could understand why this was so but I am will muddled on it. I surmise that somehow my dialog's modal event loop has hijacked the app's event loop so that when the dialog ends so does the app.
If anybody has a better understanding of this mistake please feel free to enlighten us...
Thanks to all for reading and suggestions.
PS -- I changed my code to use [NSApplication runModalForWindow:] instead of the modal session calls and all is well (I think). (Using the modal session would allow me to launch a web browser from a modal dialog -- while runModalForWindow does not -- but in this case I don't need that functionality.)
At a great number of requests from people using older iOS hardware, I'm currently refactoring and optimizing my app so it will work on iOS 3. That being said I've got a glitch with my UITabBar that I can replicate on all of the iPhone 3G units I've tested it on.
The glitch appears to have been fixed in iOS 4, but I was wondering if before that time, anyone else had this glitch as well and had figured out a (relatively elegant) workaround for it.
The problem is what you can see below; when a memory warning occurs and all of the views offscreen are released, when I bring a view controller with a tab bar back on screen, all of the UITabBarItems that are supposed to be in it are gone. As far as I can see, they're not being drawn at all; ie tapping the tab bar has no effect. After setting breakpoints and examining the UITabBar and its items in memory, they're all still there (ie not getting released), just that they're not getting redrawn when the UITabBar is re-created in the controller loadView method.
My app works similar to the official Twitter app in that I implemented my own version of UITabBarController so I could control the integration of it with a parent UINavigationController properly. I set it up as closely as possible to the original UITabBarController class though, with all of the child view controllers handling their own respective UITabBarItems and initializing them inside the class' init methods. Once the child view controllers are passed to my TabController object via an accessor method, the tabBarItems are accessed and added to the UITabBar view.
Has anyone seen this behaviour before and know of a way I can fix it? I'm hoping there's a really simple fix for this since it already works in iOS 4, so I don't want to hack it up too badly.
Thanks a lot!
After a bit of research, I think I found a solution to this. It's not the most elegant solution I was after, but it definitely works.
I'm guessing after a memory warning is triggered, something is happening to the UITabBarItem objects that basically renders them corrupt. I tried a lot of things (flushing out the UITabBar, re-creating the controllers array etc), but nothing worked.
I finally discovered that if you completely destroy the UITabBarItems and allocate new ones in their place, then those ones will work. :)
So my final solution to this was to add an extra condition in the viewDidLoad method of my controller that if the detected system was iOS 3, and there was already an array of UITabBarItems, it would go through each one, copy out all of the properties needed, destroy it, allocate a new one and then copy the old properties over to the new one.
I'm still going to keep an eye out for a better solution (I think there's a bit of overhead in this method), but thankfully at this stage, iOS 3 legacy support is becoming less and less of an issue. :)
I have a nib file I've loaded like so [NSBundle loadNibNamed: #"myNibFile" owner: self ] and it pops up fine, but when it loses focus, it simply disappears. I've checked to see if it's vanishing behind my main window but it's not. My app is pretty big so I'm not sure what could be causing it. I have garbage collection enabled if that makes any difference. Does anyone know of any problems with loaded nib files and losing focus that I should look into? If necessary I can start posting some samples from my code.
Hmmm... I just deleted the nib I was loading and recreated it and it started working. Strange... Seems fixed now though.