我对Objective-C和编码比较陌生。我已经尝试过自己做一个小开发但现在已经陷入了可能是新手错误的问题。 我创建了一个带有5个视图的标签栏控制器,其中一个视图是UIWebView。我有Webview工作并加载,但当我选择一个不同的选项卡时,应用程序崩溃。请在下面找到我的代码,任何帮助将不胜感激!
#import <UIKit/UIKit.h>
@interface LiveViewController : UIViewController {
IBOutlet UIWebView *liveView;
}
@property (nonatomic, retain) UIWebView *liveView;
@end
#import "LiveViewController.h"
@implementation LiveViewController
@synthesize liveView;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[self.liveView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.britishseapower.co.uk/live/"]]];
[super viewDidLoad];
}
- (void)webViewDidStartLoad:(UIWebView *)liveView
{
// starting the load, show the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)liveView
{
// finished loading, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)liveView:(UIWebView *)liveView didFailLoadWithError:(NSError *)error
{
// load error, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
// report the error inside the webview
NSString* errorString = [NSString stringWithFormat:
@"<html><center><font size=+5 color='red'>An error occurred:<br>%@</font></center></html>",
error.localizedDescription];
[self.liveView loadHTMLString:errorString baseURL:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
if ( [self.liveView loading] ) {
[self.liveView stopLoading];
}
self.liveView.delegate = nil; // disconnect the delegate as the webview is hidden
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)dealloc {
[liveView release];
[UIWebView release];
[LiveViewController release];
[super dealloc];
}
@end
非常感谢,
赖安
答案 0 :(得分:2)
[UIWebView release]; [LiveViewController release];
这就是让您的应用崩溃的原因。
向类本身发送释放消息无效。
您使用[liveView release];
所做的就足够了(通过调用[super dealloc];
。)
您还应该在dealloc方法中将委托设置为nil,如viewWillDisappear方法self.liveView.delegate = nil;
中所示。这样您就可以避免从UIWebView发送到LiveViewController的任何进一步消息。
您应该阅读更多有关Objective-C的文档,以便更好地了解它的工作原理。
答案 1 :(得分:1)
不确定这是否相关但我注意到您没有将自己设置为代码中的委托,这意味着它必须在Interface Builder中连接。现在,当视图消失时,您正在断开该连接,但如果视图要重新显示并且之前未卸载,则该连接将保持断开状态。
答案 2 :(得分:1)
应用程序可能崩溃的最常见原因之一是引用或向已经从内存中释放的对象发送消息。使用NSZombieEnabled并查看控制台消息可以轻松找到这种类型的错误。因此,如果您还没有尝试过,那么您必须做的第一件事就是这样。
问题可能在LiveViewController中,但也可能在其他视图控制器中。我不相信LiveViewController中的问题是100%,因为视图控制器在视图未显示时不会尝试释放其视图,除非它获得内存警告。并且您使用模拟器运行应用程序,除非您模拟一个,否则它不太可能有内存警告。
您可能知道视图控制器永远不会创建视图,除非视图由对象使用。其他视图控制器之一可能在其视图加载过程中有一个愚蠢的错误,导致崩溃。或者,您可能错误地释放了另一个视图控制器。当你在他们的视图之间不断变换时(不显示LiveViewController),100%确保其他视图控制器自己显示他们的视图没有问题。
所以我要做的是尝试NSZombieEnabled并检查它是否访问已发布的对象,如果是,则对象是什么。此外,我将仔细检查问题是否与LiveViewController有关。如果它没有帮助,我将在LiveViewController及其liveView被释放时记录消息(对于liveView,您需要将其子类化)。因为delegate
属性几乎总是不保留对象,所以如果LiveViewController对象被释放(这不应该发生)并且liveView仍然在委托属性中引用它,那么它将会崩溃。
答案 3 :(得分:0)
这样的崩溃几乎总是与释放已经释放和解除分配的对象有关
让XCode帮助您找到错误。在XCode 4中:
- 在工具栏中,选择方案列表,然后选择“编辑方案”
- 在左侧列表中选择“Run Your.app”。
- 在“环境变量”下,在相应的列中添加以下名称/值对:
CFZombieLevel 3
NSZombieEnabled 是
现在,在调试应用程序时,您将收到一条消息,告知在已经具有-retainCount为零的对象上调用-release。现在你有一个很好的线索开始你的调查。
请注意,这些标志会阻止对象被释放,因此最好根据需要将其打开以防止出现内存不足错误。