Search code examples
iosobjective-cxcodebuildllvm

Xcode 8 with "Release: Fastest, Smallest [-Os]" have some weird issue and not functional well in some case


I have 1 target in my project and have 3 build configuration

Debug Production & Release

While I am running my app with debug or production configuration and its working fine with no issues at all, but when I change my build configuration to release it's giving me some weird issues like some string values are not storing in plist file and when I debug my release mode, I didn't get any value in my debugger.

After too much investigation on my code and build setting and some suggestions from SO I have done the below change in my Build setting as mentioned below.

Change Optimization Level under Apple LLVM 8.0 Code Generation header

Getting issue in below Optimization level:

enter image description here

Resolved issue with below change in Optimization level:

enter image description here

Don't know why it's working in None[-O0].

Can anyone help me with the above patch?

Here is one sensitive part where the above Optimisation level affected.

My saved bookmark code where I have value but still it's storing NULL in plist.

- (IBAction)bookmark:(id)sender{
    
    DimensionModel *aDimensionModel = APPDELEGATE.selected_dimensionModel;
    EmirateModel *aEmirateModel = APPDELEGATE.selected_emirateModel;
    DivisionModel *aDivisionModel = APPDELEGATE.selected_divisionModel;
    __weak NSString *aStrVCName = self.bookMarkViewModel.selectedStrVCName;
    
    //Add Title string in Dictionary and then in Plist
    __weak NSString *aStrTitle = [NSString stringWithFormat:@"%@",aDimensionModel.dimension_description];
    aStrTitle = [aStrTitle stringByReplacingOccurrencesOfString:@"(null)" withString:@""];
    
    if (IS_ENGLISH) {
        aStrTitle = [aStrTitle stringByAppendingString:[NSString stringWithFormat:@" - %@ - %@ - %@",aDivisionModel.division_name,aEmirateModel.emirate_name,[self.bookMarkViewModel.strDataType isEqualToString:@"Number"]?@"(0)":@"(%)"]];
    }else{
        aStrTitle = [aStrTitle stringByAppendingString:[NSString stringWithFormat:@" - %@ - %@ - %@",aDivisionModel.division_name,[Utilities getEmirateNameinArabicByCode:aEmirateModel.emirate_code],[self.bookMarkViewModel.strDataType isEqualToString:@"Number"]?@"(0)":@"(%)"]];
    }
    
    if (APPDELEGATE.selectedDimRecordTimeModel.record_year == -1) {
        aStrTitle = [aStrTitle stringByAppendingString:[NSString stringWithFormat:@" - %@",[LanguageUtility getLocalizedStringForKey:@"All Years"]]];
    }else{
        aStrTitle = [aStrTitle stringByAppendingString:[NSString stringWithFormat:@" - %ld",(long)APPDELEGATE.selectedDimRecordTimeModel.record_year]];
    }
    
    
    NSMutableDictionary *aMutDicGraphDetail = [NSMutableDictionary new];
    
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",self.bookMarkViewModel.strSelectedDim] forKey:@"DimCode"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",aStrVCName] forKey:@"VCName"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",PLIST_TITLE_BOOKMARK] forKey:@"PlistBookmark"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",IS_ENGLISH?@"ENGLISH":@"ARABIC"] forKey:@"Language"];
    if (self.bookMarkViewModel.strSelectedDim == nil) {
        [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",[LanguageUtility getLocalizedStringForKey:aStrVCName]] forKey:@"Title"];
    }else{
        [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",aStrTitle] forKey:@"Title"];
    }
    
    
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",APPDELEGATE.selectedDimRecordTimeModel.record_time] forKey:@"RecordTime"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%ld",(long)APPDELEGATE.selectedDimRecordTimeModel.record_year] forKey:@"RecordYear"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",aEmirateModel.emirate_code] forKey:@"EmirateCode"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",self.bookMarkViewModel.strDataType] forKey:@"DataType"];
    
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",aDivisionModel.division_code] forKey:@"DivisionCode"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%d",APPDELEGATE.isDataTypeSwitchHide] forKey:@"switchHide"];
    [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",APPDELEGATE.strYearOrMonthFromRbtnCtrl] forKey:@"YearOrMonthFromRbtnCtrl"];
    [aMutDicGraphDetail setObject:@(self.bookMarkViewModel.selectedIndexPath).stringValue forKey:DimSelectedIndex];
    
    /* Check for RegionVC  and CountryVC*/
    if ([aStrVCName isEqualToString:@"RegionMainVC"] || [aStrVCName isEqualToString:@"CountryMainVC"]){
        [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%@",self.bookMarkViewModel.strComparison] forKey:@"Comparison"];
        [aMutDicGraphDetail setObject:[NSString stringWithFormat:@"%ld",self.bookMarkViewModel.intSelectedRegionId] forKey:@"RegionId"];
    }
    [self.bookMarkViewModel saveBookmark:aMutDicGraphDetail];
    
    aStrVCName = nil;
}

Using the above code all values are successfully stored into plist but aStrTitle has value in it and still, it's storing as null.


Solution

  • Your problem is in this line:

    __weak NSString *aStrTitle = [NSString stringWithFormat:@"%@",aDimensionModel.dimension_description];
    

    +[NSString stringWithFormat:] creates a new string with retain count equal to zero. And this is usually okay, since this value is either assigned to a strong variable or passed as a parameter to the method call. In both cases it's retain count gets incremented and the value remains untouched. But you are assigning this new string to the __weak variable! Weak variables don't affect retain count so it remains zero after this line executed. And so the created string gets deleted immediately after creation.

    Solution is simple: remove __weak specifier and you'll be good to go.

    There is no point in declaring local variables as weak (unless they are captured by the blocks). Also "cleanups" like this one: aStrVCName = nil; have no effect at all.

    • All local variables are automatically released when the method finishes its execution.
    • aStrVCName is weak anyway, so it never affects retain counts of the objects it's pointing to.