是对PRESViewController的ARC内存管理:动画:完成:在iOS 6.x中被破坏了吗?

Dir*_*nry 8 modalviewcontroller ios ios5 ios6

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

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

*** -[WebBrowser isKindOfClass:]: message sent to deallocated instance 0x1f640ac0
Run Code Online (Sandbox Code Playgroud)

我的代码使用的是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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

WebBrowser *browser = [[WebBrowser alloc] initWithURL:URL];
[self presentViewController:browser animated:YES completion:NULL];
Run Code Online (Sandbox Code Playgroud)

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

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

原始邮政

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

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

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

然后,发生以下错误

*** -[GKLeaderboardViewController isKindOfClass:]: message sent to deallocated instance 0x17467120
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

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

Game Center成就视图控制器或我的任何其他自定义视图控制器都会显示同样的情况presentModalViewController:.

似乎用presentModalViewController:presentViewController:animated:completion:DOES 替换已弃用的指令也无法解决问题.

Sul*_*han 1

我看到至少一个可能的问题:

[self.webView stopLoading];
self.webView.delegate = nil;
Run Code Online (Sandbox Code Playgroud)

一般来说,在调用之前delegate设置为比较安全。nilstopLoading

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];
}
Run Code Online (Sandbox Code Playgroud)