在iOS6.0上使用FBNativeDialogs发布到facebook时发生不一致的崩溃

在iOS6.0上使用FBNativeDialogs发布到facebook时发生不一致的崩溃,ios,objective-c,facebook-ios-sdk,fbnativedialogs,Ios,Objective C,Facebook Ios Sdk,Fbnativedialogs,我已经为这个问题挣扎了一段时间,但我似乎无法准确地再现它,以描述确切的用例。本质上,我所做的是发出打开本机iOS 6.0 Facebook共享对话框的请求(使用Facebook iOS SDK 3.1.1): 在调用presentShareDialogModallyFrom:sender之后,我会得到以下崩溃日志: *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection

我已经为这个问题挣扎了一段时间,但我似乎无法准确地再现它,以描述确切的用例。本质上,我所做的是发出打开本机iOS 6.0 Facebook共享对话框的请求(使用Facebook iOS SDK 3.1.1):

在调用
presentShareDialogModallyFrom:sender
之后,我会得到以下崩溃日志:

*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x1d161490> was mutated while being enumerated.'
*** First throw call stack:
(0x32ede2a3 0x326b097f 0x32eddd85 0x35da094d 0x32edb62f 0x35da07f5 0x35e7e5e5 0x35e0ccd7 0x35e0cb6d 0x372c490f 0x35e0ca61 0x35e160d5 0x372b783b 0x35e160b1 0x372b711f 0x372b699b 0x372b6895 0x372c5215 0x372c53b9 0x36f5fa11 0x36f5f8a4)
libc++abi.dylib: terminate called throwing an exception
***由于未捕获的异常“NSGenericeException”而终止应用程序,原因:“***集合在枚举时发生了变异。”
***第一次抛出调用堆栈:
(0x32ede2a3 0x326b097f 0x32eddd85 0x35da094d 0x32edb62f 0x35da07f5 0x35E7E50x35E0CCD7 0x35e0cb6d 0x372c490f 0x35e0ca61 0x35e160d5 0x372B783B0x35E160B1 0x372b711f 0x372b699b 0x372b6895 0x372c5215 0x372c53b9 0x36f5fa11 0x36f5f8a4)
libc++abi.dylib:terminate调用引发异常
我没有遇到崩溃,本机共享对话框显示正常


堆栈意味着调用名为
UIRemoteViewControllerCreationRequest
的线程。此时,这里有两个两种不同崩溃的示例:


感谢您的帮助

我想您知道什么是显而易见的,但我曾经遇到过这个错误,它是一个NSMutableArray,在for..in语句中枚举时发生了变异

查看NSMutableArray,您会发现错误


顺便说一句,如果你的目标是ios6,为什么不将社交框架与本机facebook实现结合使用呢

这是一种非常奇怪的向Facebook发帖的方式。这里有一个更简单的方法,永远不会崩溃

ViewController.h

#import <UIKit/UIKit.h>
#import <Social/Social.h>
#import <Accounts/Accounts.h>

@interface ViewController : UIViewController {
SLComposeViewController *mySLComposerSheet;
}
- (IBAction)PostToFacebook:(id)sender;

@end

如果需要的话,会有一段视频

对不起,有些是猜测,但我想我会试试:

您确定从非UI线程调用canPresentShareDialogWithSession是安全的吗

您在两个_NSDictionaryEnumerate堆栈中都有一行。从更高的函数来看,似乎有东西在调用enumerateKeysAndObjectsUsingBlock:

基于您在[presentShareDialogModallyFrom:sender]之后发生崩溃的记录。当发送者的视图消失时,是否有内容被释放


变量“image”要么保留要么自动删除,这取决于它所采用的代码路径。

我认为问题在于Walt已经说过了。在代码中,某些操作是在主线程之外完成的


在崩溃日志中,您可以看到有人正在从非UI线程设置某个UI元素的外观(UIAppearance)。这就是问题所在。此操作只能在UI(主)线程中完成。

我认为这与UIAppearance方法的组合以及从后台线程启动UIRemoteViewController有关。我们的应用程序中存在相同的问题。我将更改presenter类,从主线程显示所有远程ViewController,看看这是否有帮助

在你的例子中,我猜Facebook SDK中的某些东西是从后台线程中呈现出来的


我将在验证我的修复程序是否有效后进行更新。

在对我的应用程序进行了大量试验并查看Facebook SDK源代码后,我意识到了三件事:

  • 自己创建
    SLComposeViewController
    没有帮助。FacebookSDK在这方面非常简单,它只是创建了一个与答案中的代码完全相同的控制器

  • 当您授权FB会话时,您的应用程序将被停用一次或多次。这是由于出现权限确认警报造成的

  • UIRemoteViewController
    实际上是在不同进程中运行的
    SLComposeViewController

  • 是什么导致了我的错误

  • 用户确认FB权限
  • 这将触发ApplicationIDBecomeActive:
  • 它还触发FB回调以显示对话框
  • My
    ApplicationIDBecomeActive:
    正在对UI执行一些在FB对话框出现时不应该执行的操作(使表格重新加载变得疲劳)
  • 另外,还有一件事需要注意-在任何特定线程上都不会调用来自…的
    presentShareDialogModallyFrom的处理程序(请参见
    SLComposeViewController
    docs)。这意味着您应该使用处理程序中的
    dispatch\u async(dispatch\u get\u main\u queue(),…)
    来更新UI

    编辑:
    显然,前面的步骤修复了一些崩溃,但其中一个崩溃没有得到解决。在谷歌搜索了很多苹果开发者论坛之后,我认为iOS 6中有一个bug,它与远程控制器连接,使用的是
    UIAppearance
    ,尤其是
    UINavigationBar
    的外观。我目前正在从我的应用程序中删除
    uiappearance

    这是iOS 6和社交框架中的一个bug,请检查此处的答案

    如何解决这个问题?

    只需使用
    [UINavigationBar外观]
    而不使用
    [UINavigationBar外观,如果包含在其中:…]

    您可以为导航控制器(例如CustomNavigationController)使用自定义类,然后在外观中应用它:

    [UINavigationBar在:[CustomNavigationController类]中包含时的外观,无]


    根据我的实验,它应该用在所有
    外观
    方法上,不仅
    UINavigationBar
    ,而且
    UIBarButtonItem
    等(在您发送
    外观
    消息到的每个对象上)

    UIRemoteViewControllerCreationRequest是线程名称的一部分。您需要使用堆栈下方的滑块展开线程堆栈。然后我们可以看到堆栈中的所有调用。谢谢,编辑过的问题从何处调用您的代码段(例如,viewDidLoad或某个iAction)?iAction调用此实例方法,该方法声明为“SocialManager”单例的一部分。我有
    #import <UIKit/UIKit.h>
    #import <Social/Social.h>
    #import <Accounts/Accounts.h>
    
    @interface ViewController : UIViewController {
    SLComposeViewController *mySLComposerSheet;
    }
    - (IBAction)PostToFacebook:(id)sender;
    
    @end
    
    - (IBAction)PostToFacebook:(id)sender {
    mySLComposerSheet = [[SLComposeViewController alloc] init];
    mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    [mySLComposerSheet setInitialText:@"Place Text Here"];
    [self presentViewController:mySLComposerSheet animated:YES completion:nil];
    }
    @end