__weak SLComposeViewController在IOS 8中导致崩溃

时间:2015-01-07 23:29:14

标签: objective-c facebook weak-references slcomposeviewcontroller retain-cycle

IOS 8中的SLComposeViewController存在问题。我想显示Facebook共享窗口,并在完成后显示Twitter共享窗口。这就是为什么我需要使用完成块并避免保留周期我必须使用 __ weak SLComposeViewController ,但是当我调用时

  

[viewController presentViewController:facebookSLController animated:YES completion:Nil];

我的facebookSLController是零。这是因为__weak。但为什么它在IOS 7中没有崩溃? 我该如何解决这个问题?以下是代码的一部分:

if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {

    __weak SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

    [controller setInitialText:text];

    //When facebook sharing end - we start twitter sharing
    [controller setCompletionHandler:^(SLComposeViewControllerResult result) {
        [controller dismissViewControllerAnimated:YES completion:nil];
        [self shareTwitterImage:image withText:strGetApp fromViewController:viewController];
    }];


    [controller addImage:image];

    [viewController presentViewController:controller animated:YES completion:Nil];

}

1 个答案:

答案 0 :(得分:2)

问题是你在不知道自己在做什么的情况下搞乱内存管理。你的代码毫无意义。声明变量weak并将新创建的实例分配给该变量意味着该实例将立即不存在 - 因为没有任何东西可以保留它。通常,变量的强引用是保留变量的,但通过声明变量weak,您已经阻止了它。因此,您可能希望controller在您宣布它的瞬间消失在烟雾中 - 这就是它正在做的事情。此代码从不在iOS 7或iOS 8中正常工作。

如果你想通过弱引用将通过controller引用的视图控制器传递给块,那么就这样做;将另一个引用,一个弱引用引用到controller并让它传递到块中(并执行"弱强舞"使用它,以便你的块行为正确)。但controller 本身需要是正常参考。因此(警告,直接键入而不进行测试,谨防拼写错误):

SLComposeViewController *controller = 
    [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controller setInitialText:text];
// take a weak ref to pass into the block
__weak SLComposeViewController *weakController = controller;
[controller setCompletionHandler:^(SLComposeViewControllerResult result) {
    // and now do the weak-strong dance with weakController...
    // and do NOT refer to controller inside the block
    SLComposeViewController *strongController = weakController;
    if (strongController != nil) {
        // ... your code here; refer only to strongController
    }
}