NSString codificada se convierte, restos NSString “normales” no válidos
Pregunta
Estoy corriendo en un problema con una cadena que contiene caracteres codificados. En concreto, si la cadena de caracteres ha codificado con el tiempo deja de ser válida, mientras que una cadena "normal" no.
en el archivo .h:
@interface DirViewController : TTThumbsViewController
<UIActionSheetDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate>
{
NSString *sourceFolder;
NSString *encodedSourceFolder;
}
@property (nonatomic, retain) NSString *sourceFolder;
@property (nonatomic, retain) NSString *encodedSourceFolder;
en el archivo .m:
- (id)initWithFolder:(NSString*)folder query:(NSDictionary*)query {
if (self = [super init]) {
sourceFolder = folder;
}
return self;
}
Hasta ahora todo parece funcionar como se espera. En viewDidLoad tengo el siguiente:
sourceFolderCopy = [self urlEncodeValue:(sourceFolder)];
//I also have this button, which I'll refer to later:
UIBarButtonItem *importButton = [[UIBarButtonItem alloc] initWithTitle:@"Import/Export" style:UIBarButtonItemStyleBordered
target:self
action:@selector(importFiles:)];
self.navigationItem.rightBarButtonItem = importButton;
¿Qué utiliza el siguiente método para codificar la cadena (si tiene caracteres que quiero codificada):
- (NSString *)urlEncodeValue:(NSString *)str {
NSString *result = (NSString *) CFURLCreateStringByAddingPercentEscapes (kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8);
return [result autorelease];
}
Si el resultado de que NSLog, consigo los valores esperados. Si la cadena tiene caracteres como un espacio en blanco, me sale una cadena con codificación. Si la cadena no tiene ningún carácter que necesitan ser codificado, sólo me da la cadena original.
Tengo un botón en la barra de navegación que se inicia un proceso de importación de imágenes mediante la apertura de una hoja de acción. Una vez que el método para la acción comienza hoja, mi cadena no es válida - pero sólo si contiene caracteres codificados. Si es sólo una cadena "normal", todo está bien y funciona como se esperaba. ¿Estoy fuera de mi codificación? Al principio pensé que podría ser un problema de memoria, pero no puedo entender por qué eso afectaría solamente cadenas codificadas.
Aquí es donde se define la hoja de la acción (y el primer lugar que se puede ver la cadena codificada convertirse inválida) los estados NSLog son donde se bloquea:
- (IBAction)importFiles:(id)sender {
NSLog(@"logging encodedSF from import files:");
NSLog(@"%@",encodedSourceFolder);//crashes right here
NSLog(@"%@",sourceFolder);
if (shouldNavigate == NO)
{
NSString *msg = nil;
msg = @"It is not possible to import or export images while in image selection mode.";
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Unable to Import/Export"
message:msg
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[msg release];
}
else{
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"What would you like to do?"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Import Photos (Picker)", @"Export Photos", nil, nil];
[actionSheet showInView:self.view];
[actionSheet release];
}
}
No se deje cualquier error de choque que van a la consola. Mediante el uso de los puntos de interrupción pude ver que el encodedSourceFolder no es válida en el método de hoja de acción.
No hay solución correcta
Otros consejos
Se debe copiar la cadena transferida carpeta en su initWithFolder: consulta: método como este o crear una nueva cadena con:
- (id)initWithFolder:(NSString*)folder query:(NSDictionary*)query {
if (self = [super init]) {
sourceFolder = [folder copy];
}
return self;
}
De lo contrario su cadena se autoreleased en otro lugar.
Do no retain
uso de propiedades NSString
. Uso copy
:
@property (nonatomic, copy) NSString *sourceFolder;
Hay varias preguntas / respuestas aquí que explican más a fondo, como la respuesta de Chris Hanson en: