是否在iOS 6.x中对presentViewController的ARC内存管理:动画:完成:中断了吗?

我的视图控制器通过presentViewController:animated:completion:方法呈现视图.视图很好.

然后我关闭这个视图并重新呈现它并得到以下崩溃:

*** -[WebBrowser isKindOfClass:]: message sent to deallocated instance 0x1f640ac0

我的代码使用的是ARC.这是我的WebBrowser类的代码,一个简单的嵌入式浏览器.

WebBrowser.h:

@interface WebBrowser : ITViewController <UIWebViewDelegate,UIAlertViewDelegate>

@property (nonatomic,strong) NSString *URL;
@property (nonatomic,weak) IBOutlet UIWebView *webView;
@property (nonatomic,weak) IBOutlet UIActivityIndicatorView *spinner;

- (id)initWithURL:(NSString *)URL;
- (IBAction)dismissView:(id)sender;

@end

WebBrowser.m:

@implementation WebBrowser

- (id)initWithURL:(NSString *)URL_ {
    self = [super initWithNibName:@"MyNib" bundle:nil];
    if (self) {
        self.URL = URL_;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.webView.delegate = self;

    if (self.URL) {
        [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.URL]]];
    }
}

- (IBAction)dismissView:(id)sender {
    self.URL = nil;
    [self.webView stopLoading];
    self.webView.delegate = nil;
    [self dismissViewControllerAnimated:YES completion:NULL];
}

// + some non-related web view delegate stuff 

@end

最后,我在父视图控制器中呈现视图:

WebBrowser *browser = [[WebBrowser alloc] initWithURL:URL];
[self presentViewController:browser animated:YES completion:NULL];

我正在运行iOS 6并使用ARC进行编译.

首先我认为这个bug与ARC有关.这是我的原帖:

原始邮政

我注意到在我的应用程序中使用iOS 6.x时显示模态视图控制器并在它与以前版本的iOS工作正常时释放它.

怪我没有使用ARC(这是我在这个项目上的下一个重要步骤),但是,例如,当使用以下代码显示Game Center排行榜时,请执行以下步骤:

>显示排行榜
>关闭排行榜
>再次显示排行榜(PRECISION UPDATE:通过运行下面显示的相同showLeaderboard,即显示GKLeaderboardViewController的新实例)

然后,发生以下错误

*** -[GKLeaderboardViewController isKindOfClass:]: message sent to deallocated instance 0x17467120

这是我的代码:

- (void)showLeaderboard {
    if ([[GKLocalPlayer localPlayer] isAuthenticated]) {
        GKLeaderboardViewController *lb = [[GKLeaderboardViewController alloc] init];
        lb.category = ...;
        lb.leaderboardDelegate = self;
        self.modalPresentationStyle = UIModalPresentationCurrentContext;
        [self presentModalViewController:lb animated:YES];
        [lb release];
    } else {
        ...
    }
}

- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController{
    [self dismissModalViewControllerAnimated:YES];
}

事实证明,删除[lb release]指令解决了我的问题,并再次证明iOS 5.x没有发生此类崩溃.

使用presentModalViewController时,Game Center成就视图控制器或我的任何其他自定义视图控制器也会出现同样的情况.

似乎用新的presentViewController替换了deprecated-presentModalViewController:指令:animated:completion:不解决问题.

解决方法

我看到至少一个可能的问题:
[self.webView stopLoading];
self.webView.delegate = nil;

通常,在调用stopLoading之前将委托设置为nil更安全.

此外,以它应该使用的方式使用dismissViewControllerAnimated肯定更安全,也就是说,在呈现控制器上调用它.虽然文档说明调用是传递给呈现控制器的,但是在方法内部释放的对象上调用方法并不是一个好主意.

- (IBAction)dismissView:(id)sender {
    // pass the event to the presenting controller
    // the presenting controller should call [self dismissViewControllerAnimated:YES completion:NULL];
}

- (void)viewWillDissapear {
  [super viewWillDissapear];

   //no need to do this,it's done automatically in ARC
   //self.URL = nil;

   self.webView.delegate = nil;
   [self.webView stopLoading];
}

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...