【问题标题】:Terminating app due to uncaught exception 'NSInvalidArgumentException Xcode 9.1 / iPhone X由于未捕获的异常“NSInvalidArgumentException Xcode 9.1 / iPhone X”而终止应用程序
【发布时间】:2018-04-23 22:12:17
【问题描述】:

我的应用程序在我的 iPhone 设备和 iPad 以及除 iPhone X 模拟器之外的所有模拟器和 iOS 上都能完美运行...它在应用程序启动之前崩溃并出现以下错误日志;

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'

*** First throw call stack:
(
    0   CoreFoundation                      0x00000001127aa1ab __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000011078af41 objc_exception_throw + 48
    2   CoreFoundation                      0x00000001127e9f9c _CFThrowFormattedException + 194
    3   CoreFoundation                      0x00000001126beb41 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 321
    4   CoreFoundation                      0x000000011281d11b __createDictionary + 43
    5   CoreFoundation                      0x0000000112728cff +[NSDictionary dictionaryWithObject:forKey:] + 47
    6   ChristmasCountdown                  0x000000010dc776a4 -[Home viewDidLoad] + 20900
    7   UIKit                               0x0000000115cb38a5 -[UIViewController loadViewIfRequired] + 1235
    8   UIKit                               0x0000000115cfb1ec -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 68
    9   UIKit                               0x0000000115cfb528 -[UINavigationController _startTransition:fromViewController:toViewController:] + 153
    10  UIKit                               0x0000000115cfc63f -[UINavigationController _startDeferredTransitionIfNeeded:] + 841
    11  UIKit                               0x0000000115cfd8c3 -[UINavigationController __viewWillLayoutSubviews] + 150
    12  UIKit                               0x0000000115f56a49 -[UILayoutContainerView layoutSubviews] + 231
    13  UIKit                               0x0000000115bdf6f5 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1439
    14  QuartzCore                          0x0000000113b933ee -[CALayer layoutSublayers] + 153
    15  QuartzCore                          0x0000000113b974dd _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 401
    16  QuartzCore                          0x0000000113b1fded _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 365
    17  QuartzCore                          0x0000000113b4b704 _ZN2CA11Transaction6commitEv + 500
    18  UIKit                               0x0000000115b29d3a __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 141
    19  CoreFoundation                      0x000000011274d18c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    20  CoreFoundation                      0x000000011273196b __CFRunLoopDoBlocks + 203
    21  CoreFoundation                      0x0000000112731144 __CFRunLoopRun + 1300
    22  CoreFoundation                      0x00000001127309b9 CFRunLoopRunSpecific + 409
    23  GraphicsServices                    0x000000011467a9c6 GSEventRunModal + 62
    24  UIKit                               0x0000000115b0e5e8 UIApplicationMain + 159
    25  ChristmasCountdown                  0x000000010dc724df main + 111
    26  libdyld.dylib                       0x000000011594fd81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我不明白的是,其他模拟器工作正常,手机和平板电脑,以及相同的 iOS 版本 (11.1),所以它似乎只针对 iPhoneX...

viewDidLoad;

- (void)viewDidLoad {
    [super viewDidLoad];
   // Do any additional setup after loading the view.

    tag = 1000;
    str_Type = @"Current";

    //Set Navigation Bar Title
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
    label.backgroundColor = [UIColor clearColor];
    label.font = [UIFont boldSystemFontOfSize:20.0];
    label.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = @"Christmas Countdown";
    label.textColor = [UIColor whiteColor];
    self.navigationItem.titleView = label;

    //Hide Not Required UILabel's
    lbl_Time.hidden = YES;
    lbl_Text.hidden = YES;
    lbl_Days.hidden = YES;
    lbl_DaysText.hidden = YES;
    lbl_Weeks.hidden = YES;
    lbl_WeeksText.hidden = YES;
    img_DividerImage.hidden = YES;

    //Initialize NSArray object with Images
    arr_OfSanta = @[[UIImage imageNamed:@"santa1"],[UIImage imageNamed:@"santa2"],[UIImage imageNamed:@"santa3"],[UIImage imageNamed:@"santa4"],[UIImage imageNamed:@"santa5"],[UIImage imageNamed:@"santa6"]];

    //Initialize arr_MusicFiles & arr_MusicText Array
    arr_MusicFiles = @[@"auld-lang-syne-piano",@"ave-maria",@"away-in-a-manger-epiano",@"carol-of-the-bells",@"come-from-stars",@"ding-dong-merrily",@"god-rest-ye-merry-gentlemen",@"herald",@"jingle-bells-country",@"joy-to-the-world",@"o-christmas-tree",@"o-come-all-ye-faithful",@"o-holy-night",@"silent-night-piano",@"we-wish-you-a-merry-christmas"];

    arr_MusicText = @[@"Auld Land Syne Piano",@"Ave Maria",@"Away In A Manger Epiano",@"Carol Of the Bells",@"Come From Stars",@"Ding Dong Merrily",@"God Rest ye Merry Gentlemen",@"Herald",@"Jingle Bells Country",@"Joy To the World",@"O Christmas Tree",@"O Come All Ye Faithful",@"O Holy Night",@"Silent Night Piano",@"We Wish You A Merry Christmas"];

    arr_OfCountryCode = @[@"AF",@"AL",@"DZ",@"AS",@"AD",@"AO",@"AI",@"AQ",@"AG",@"AR",@"AM",@"AW",@"AC",@"AU",@"AT",@"AZ",@"BS",@"BH",@"BD",@"BB",@"BY",@"BE",@"BZ",@"BJ",@"BM",@"BT",@"BO",@"BA",@"BW",@"BV",@"BR",@"IO",@"VG",@"BN",@"BG",@"BF",@"BI",@"KH",@"CM",@"CA",@"IC",@",CV",@"BQ",@"KY",@"CF",@"EA",@"TD",@"CL",@"CN",@"CX",@"CP",@"CC",@"CO",@"KM",@"CD",@"CG",@"CK",@"CR",@"HR",@"CU",@"CW",@"CY",@"CZ",@"CI",@"DK",@"DG",@"DJ",@"DM",@"DO",@"EC",@"EG",@"SV",@"GQ",@"ER",@"EE",@"ET",@"FK",@"FO",@"FJ",@"FI",@"FR",@"FG",@"PF",@"TF",@"GA",@"GM",@"GE",@"DE",@"GH",@"GI",@"GR",@"GL",@"GD",@"GP",@"GU",@"GT",@"GG",@"GN",@"GW",@"GY",@"HT",@"HM",@"HN",@"HK",@"HU",@"IS",@"IN",@"ID",@"IR",@"IQ",@"IE",@"IM",@"IL",@"IT",@"JM",@"JP",@"JE",@"JO",@"KZ",@"KE",@"KI",@"XK",@"KW",@"KG",@"LA",@"LV",@"LB",@"LS",@"LR",@"LY",@"LI",@"LT",@"LU",@"MO",@"MK",@"MG",@"MW",@"MY",@"MV",@"ML",@"MT",@"MH",@"MQ",@"MR",@"MU",@"YT",@"MX",@"FM",@"MD",@"MC",@"MN",@"ME",@"MS",@"MA",@"MZ",@"MM",@"NA",@"NR",@"NP",@"NL",@"NC",@"NZ",@"NI",@"NE",@"NG",@"NU",@"NF",@"KP",@"MP",@"NO",@"OM",@"PK",@"PW",@"PS",@"PA",@"PG",@"PY",@"PE",@"PH",@"PN",@"PL",@"PT",@"PR",@"QA",@"RO",@"RU",@"RW",@"RE",@"WS",@"SM",@"SA",@"SN",@"RS",@"SC",@"SL",@"SG",@"SX",@"SK",@"SI",@"SB",@"SO",@"ZA",@"GS",@"KR",@"SS",@"ES",@"LK",@"BL",@"SH",@"KN",@"LC",@"MF",@"PM",@"VC",@"SD",@"SR",@"SJ",@"SZ",@"SE",@"CH",@"SY",@"ST",@"TW",@"TJ",@"TZ",@"TH",@"TL",@"TG",@"TK",@"TO",@"TT",@"TA",@"TN",@"TR",@"TM",@"TC",@"TV",@"UM",@"VI",@"UG",@"UA",@"AE",@"GB",@"US",@"UY",@"UZ",@"VU",@"VA",@"VE",@"VN",@"WF",@"EH",@"YE",@"ZM",@"ZW",@"AX"];

    //UIView Width
    int width = self.view.frame.size.width;

    //Current Device Model
    NSString *deviceType = [UIDevice currentDevice].model;

    //this will load wether or not they bought the in-app purchase
    areAdsRemoved = [[NSUserDefaults standardUserDefaults] boolForKey:@"areAdsRemoved"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    if ([deviceType isEqualToString:@"iPad"]) {
        if(areAdsRemoved){
             [self.scrolView_Bottom setConstant:0];

            //Hide BannerView
            self.bannerView.hidden = YES;
            self.btn_RemoveAds.hidden = YES;
            //if they did buy it, set the background to blue.

        } else {

            [self.scrolView_Bottom setConstant:100];

            //Display BannerView
            self.bannerView.hidden = NO;
        }

        //Set UIScrollView Content Size
        self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 365);
        self.srl_ScrollView.contentSize = CGSizeMake(6*width, 365);
        [self scrollViewDidScroll:self.srl_ScrollView];

        //Set Font Text Size
        objFont = [UIFont boldSystemFontOfSize:20.0];

        //Adjust Constraints
        [self.view_Bottom setConstant:100];
        [self.img_Top setConstant:140];
        [self.btnLeft_Width setConstant:150];
        [self.btnLeft_Height setConstant:200];
        [self.btnRight_Height setConstant:200];
        [self.btnRight_Width setConstant:150];
        [self.bannerView_Height setConstant:100];

        //Set UILabel Font Size
        lbl_AllDays.font = [UIFont systemFontOfSize:30.0];
        lbl_AllHours.font = [UIFont systemFontOfSize:30.0];
        lbl_AllMinutes.font = [UIFont systemFontOfSize:30.0];
        lbl_AllSeconds.font = [UIFont systemFontOfSize:30.0];
        lbl_Time.font = [UIFont systemFontOfSize:55];
        lbl_Text.font = [UIFont systemFontOfSize:35];
        lbl_Weeks.font = [UIFont systemFontOfSize:55];
        lbl_WeeksText.font = [UIFont systemFontOfSize:35];
        lbl_Days.font = [UIFont systemFontOfSize:55];
        lbl_DaysText.font = [UIFont systemFontOfSize:35];

        //Add Images in UIScrollView
        self.img_ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.srl_ScrollView.frame.size.height)];
        self.img_ImageView.contentMode = UIViewContentModeScaleAspectFit;
        self.img_ImageView.clipsToBounds = YES;
        self.img_ImageView.image = [arr_OfSanta objectAtIndex:0];
        [self.srl_ScrollView addSubview:self.img_ImageView];
    } else {

        if(areAdsRemoved){
            //Adjust UIScrollView Constraint
            [self.scrolView_Bottom setConstant:0];

            //Hide BannerView
            self.bannerView.hidden = YES;

            self.btn_RemoveAds.hidden = YES;
            //if they did buy it, set the background to blue.
        } else {
            //Adjust UIScrollView Constraint
            [self.scrolView_Bottom setConstant:50];

            //Display BannerView
            self.bannerView.hidden = NO;
        }

        //Current Device Screen Size
        int height = [[UIScreen mainScreen] bounds].size.height;

        //Set UILabelText Font Size, If Screen height 480
        if (height == 480) {
            //Set Font Text Size
            objFont = [UIFont boldSystemFontOfSize:9.0];

            //Set UIScrollView Content Size
            self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 150);
            self.srl_ScrollView.contentSize = CGSizeMake(6*width, 150);

            //Adjust Constraints
            [self.img_Top setConstant:50];

            //Set UILabel Font Size
            lbl_AllDays.font = [UIFont systemFontOfSize:12.0];
            lbl_AllHours.font = [UIFont systemFontOfSize:12.0];
            lbl_AllMinutes.font = [UIFont systemFontOfSize:12.0];
            lbl_AllSeconds.font = [UIFont systemFontOfSize:12.0];
            lbl_Time.font = [UIFont systemFontOfSize:25];
            lbl_Text.font = [UIFont systemFontOfSize:15];
            lbl_Weeks.font = [UIFont systemFontOfSize:25];
            lbl_WeeksText.font = [UIFont systemFontOfSize:15];
            lbl_Days.font = [UIFont systemFontOfSize:25];
            lbl_DaysText.font = [UIFont systemFontOfSize:15];
        }

        //Change Divider Image Top, When screen size grater than 480
        if (height == 568) {
            //Set Font Text Size
            objFont = [UIFont boldSystemFontOfSize:9.0];

            //Set UIScrollView Content Size
            self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 150);
            self.srl_ScrollView.contentSize = CGSizeMake(6*width, 150);

            [self.img_Top setConstant:70];
        } else if (height == 667) {
            //Set UIScrollView Content Size
            self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 240);
            self.srl_ScrollView.contentSize = CGSizeMake(6*width, 240);

            //Set Font Text Size
            objFont = [UIFont boldSystemFontOfSize:11.0];
            [self.img_Top setConstant:90];
        } else if (height == 736) {
            //Set UIScrollView Content Size
            self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 270);
            self.srl_ScrollView.contentSize = CGSizeMake(6*width, 270);

            objFont = [UIFont boldSystemFontOfSize:11.0];
            [self.img_Top setConstant:100];
        }

        //Add Images in UIScrollView
        self.img_ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.srl_ScrollView.frame.size.height)];
        self.img_ImageView.contentMode = UIViewContentModeScaleAspectFit;
        self.img_ImageView.clipsToBounds = YES;
        self.img_ImageView.image = [arr_OfSanta objectAtIndex:0];
        [self.srl_ScrollView addSubview:self.img_ImageView];
    }

    //Hide MKMapView
    self.mapView.hidden = YES;

    //Zoom In & Zoom Out Animation
    [UIView animateWithDuration:0 animations:^{
        lbl_AllDays.transform = CGAffineTransformMakeScale(0.01, 0.01);
        lbl_AllHours.transform = CGAffineTransformMakeScale(0.01, 0.01);
        lbl_AllMinutes.transform = CGAffineTransformMakeScale(0.01, 0.01);
        lbl_AllSeconds.transform = CGAffineTransformMakeScale(0.01, 0.01);
    }completion:^(BOOL finished){
        // Finished scaling down imageview, now resize it
        [UIView animateWithDuration:0.8 animations:^{
            lbl_AllDays.transform = CGAffineTransformIdentity;
            lbl_AllHours.transform = CGAffineTransformIdentity;
            lbl_AllMinutes.transform = CGAffineTransformIdentity;
            lbl_AllSeconds.transform = CGAffineTransformIdentity;
        }completion:^(BOOL finished){
            NSLog(@";Finished...");
        }];
    }];

    //Set NSTimer to Call countdownTracker method to show pending time in Christmas.
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countdownTracker:) userInfo:nil repeats:YES];

    //Add font object to Dictionary
    NSDictionary *dictAttributes = [NSDictionary dictionaryWithObject:objFont forKey:NSFontAttributeName];

    //Set dictionary to the titleTextAttributes
    [self.segmentControl setTitleTextAttributes:dictAttributes forState:UIControlStateNormal];
    [self.segmentControl setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]} forState:UIControlStateSelected];

    //Customize UISegmentControl
    [self.segmentControl setBackgroundImage:[UIImage imageNamed:@"NavigatinBackground"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    //Customize MKMapView to track Santa Location
    geocoder = [[CLGeocoder alloc] init];
    cl_LocationManager = [[CLLocationManager alloc] init];
    cl_LocationManager.delegate = self;
    cl_LocationManager.desiredAccuracy = kCLLocationAccuracyBest;
    //[cl_LocationManager requestWhenInUseAuthorization];
    [cl_LocationManager startUpdatingLocation];

    //Hide UIView's mapView
    self.mapView.hidden = YES;
    self.musicView.hidden = YES;

}

这一行会导致 iPhone X 崩溃

 //Add font object to Dictionary
        NSDictionary *dictAttributes = [NSDictionary dictionaryWithObject:objFont forKey:NSFontAttributeName];

【问题讨论】:

  • 发布你的Home班级代码
  • 里面有很多行,有什么特别的代码段吗?
  • 显然错误出在 Home 类的 viewDidLoad 方法中。使用viewDidLoad 更新您的问题并指出导致错误的确切行。
  • 完成,现在更新包括viewDidLoad
  • 我现在已经确定了确切的行,如果我将其注释掉,应用程序就会加载,但我不确定这是否是一个可行的解决方案。该行是NSDictionary *dictAttributes = [NSDictionary dictionaryWithObject:objFont forKey:NSFontAttributeName];

标签: ios xcode iphone-x


【解决方案1】:

在我的代码里面,你可以看到硬编码的字体值,比如;

if (height == 568) {
            //Set Font Text Size
            objFont = [UIFont boldSystemFontOfSize:9.0];

            //Set UIScrollView Content Size
            self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 150);
            self.srl_ScrollView.contentSize = CGSizeMake(6*width, 150);

添加特定于 iPhone X 尺寸的条目效果很好;

//iPhoneX
    } else if (height == 812) {
        //Set UIScrollView Content Size
        self.srl_ScrollView.frame = CGRectMake(0, self.srl_ScrollView.frame.origin.y, self.view.frame.size.width, 270);
        self.srl_ScrollView.contentSize = CGSizeMake(6*width, 270);

        objFont = [UIFont boldSystemFontOfSize:11.0];
        [self.img_Top setConstant:100];
    }

【讨论】:

    【解决方案2】:
    NSDictionary *dictAttributes = [NSDictionary dictionaryWithObject:objFont forKey:NSFontAttributeName];
    

    此行导致崩溃,因为objFontnil

    为什么? 因为这就是你所做的:

    if (somethingA)
    {
        objFont = someFont;
    }
    else if (somethingB)
    {
        objFont = someFont;
    }
    else if (somethingC)
    {
        objFont = someFont;
    }
    //... others else if
    else if (somethingN)
    {
        objFont = someFont;
    }
    
    NSDictionary *dictAttributes = [NSDictionary dictionaryWithObject:objFont forKey:NSFontAttributeName];
    

    您缺少的是,如果您从未通过 if/else if 测试,则 obj 字体将永远不会被初始化并导致崩溃。

    else if (somethingN)
    {
        objFont = someFont;
    }
    else 
    {
        objFont = someDefaultFont;
    }
    

    或者在声明的时候初始化objFont

    剩下的,你的代码看起来真的很乱。它可以改进,你不应该像height 那样测试来猜测模型。 您还可以添加测试“else if (height is the one of iPhone X, but that's not standard),因为如果明天 Apple 有一款具有新高度的新手机,您的代码将再次因非托管案例而崩溃,所以这样做"else" 或默认初始化。

    【讨论】:

      猜你喜欢
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多