Pregunta Xcode 8 con "Release: Fastest, Smallest [-Os]" tiene un problema extraño y no funciona bien en algunos casos


Tengo 1 objetivo en mi proyecto y tengo 3 configuración de construcción

Debug  Production & Release

Mientras estoy ejecutando mi aplicación con debug o production configuración y funciona bien sin problemas, pero cuando cambio mi build configuration a release me da algunos problemas extraños, como algunos valores de cadena no se almacenan en un archivo plist y cuando depuro mi modo de lanzamiento, no obtuve ningún valor en mi depurador.

Después de demasiada investigación sobre mi código y la configuración de construcción y alguna forma de sugerencia SO He hecho el cambio a continuación en mi configuración de compilación como se menciona a continuación.

Cambio Nivel de optimización debajo Generación de código Apple LLVM 8.0 encabezamiento

Obteniendo problemas en el siguiente nivel de optimización:

enter image description here

Se resolvió el problema con el siguiente cambio en el nivel de optimización:

enter image description here

No sé por qué está trabajando en Ninguno [-O0].

¿Alguien puede ayudarme en el parche superior?

Aquí hay una parte sensible donde el nivel de Optimización anterior se ve afectado.

Mi código de marcador guardado donde tengo valor, pero todavía está almacenando NULL en 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;
}

Usando el código anterior todos los valores se almacenan con éxito en plist, pero aStrTitle tiene valor y todavía se almacena como null.


16
2017-09-26 12:17


origen


Respuestas:


Tu problema está en esta línea:

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

+[NSString stringWithFormat:] crea una nueva cadena con retención de conteo igual a cero. Y esto generalmente está bien, ya que este valor está asignado a un strong variable o pasado como parámetro a la llamada al método. En ambos casos, se incrementa el conteo de retención y el valor permanece intacto. Pero estás asignando esta nueva cadena al __weak ¡variable! Las variables débiles no afectan el conteo de retención por lo que permanece en cero después de que se ejecute esta línea. Y entonces la cadena creada se elimina inmediatamente después de la creación.

La solución es simple: eliminar __weak especificador y estarás listo para ir.

No tiene sentido declarar las variables locales como débiles (a menos que sean capturadas por los bloques). También "limpiezas" como esta: aStrVCName = nil; no tienen efecto en absoluto.

  • Todas las variables locales se liberan automáticamente cuando el método termina su ejecución.
  • aStrVCName es débil de todos modos, por lo que nunca afecta los recuentos de retención de los objetos a los que apunta.

8
2017-10-05 08:42



Tuve un problema similar al migrar a xcode 8 y swift 3. Resulta que a swift no le gusta el hecho de que anulo las funciones de las clases base en las extensiones. ver Métodos de anulación en extensiones de Swift

Por alguna razón, el compilador no se queja, y para empeorar las cosas, los "problemas extraños" solo comenzaron a suceder en el Fastest, Smallest [-Os] nivel de optimización

Parece que en el Fastest, Smallest [-Os] nivel de optimización, el compilador llamará a la función desde la clase base, y no a la función desde la extensión. En el None [-O0] nivel de optimización, el compilador llamará a la función desde la extensión.

por ejemplo:

public class BaseController : UIViewController {
    override func reloadInterface() {
      println("ok")
    }
}

public class NewController : BaseController {
    override func viewDidLoad() {
      super.viewDidLoad()

      reloadInterface()
     }

}

extension NewController {
   override func reloadInterface() {
      println("extended function")
    }
}

imprimirá "función extendida" en ningún nivel de optimización e imprimirá "ok" en el nivel de optimización más rápido ...

para resumir la historia, no anule las funciones en extensiones rápidas


4
2017-10-04 20:01