2013-07-06 8 views
6

Sto scrivendo un'applicazione in cui è necessario inviare le immagini PNG e JPG al server. Codice per trasformare l'immagine JPEG/PNG nella stringa Base64 Ho scritto come blocco Obj-C. Ma quando ho provato ad aggiungere una stringa restituita per blocco a NSDictionary ho ottenuto code=EXC_ARM_DA_ALIGN. Nel mio progetto uso ARC. Ho letto diversi post su questo problema ARC: EXC_BAD_ACCESS when calling a method from inside a block, inside a delegate method Quindi io uso copy! Ma non mi ha aiutato. Prima di usare copy ho ottenuto EXC_BAD_EXCEPTION con codice = 1 e ora con il codice sul titolo. Ecco il mio codice:Perché ho ottenuto EXC_BAD_ACCESS_EXCEPTION (codice = EXC_ARM_DA_ALIGN) quando uso i blocchi con ARC?

__block NSUInteger image_size; 

//Obj-C block where PNG or JPEG image converts to Base64 string 

    NSString* (^ToBase64)(UIImage* imageToConvert, NSMutableDictionary* metadata) = 

    ^(UIImage* imageToConvert, NSMutableDictionary* metadata) 
{ 
    NSMutableData *rawData = [NSMutableData data]; 
    NSString* encodedImage ; 
    if ([(NSString*)[metadata objectForKey:@"extension"] isEqualToString:@"PNG"]) 
    { 
     [rawData setData:UIImagePNGRepresentation(imageToConvert)]; 
     [Base64 initialize]; 
     encodedImage = [Base64 encode:rawData]; 
     image_size = [rawData length]; 

    } 
    else if ([(NSString*)[metadata objectForKey:@"extension"] isEqualToString:@"JPG"]) 
    { 
     [rawData setData:UIImageJPEGRepresentation(imageToConvert, 1.0)]; 
     [Base64 initialize]; 
     encodedImage = [Base64 encode:rawData]; 
     image_size = [rawData length]; 
    } 
    return encodedImage; 
} ; 

//Initialize dictionary with image data and metadata to send 
int iteration = 0; 
for (UIImage* currentEntry in imagesToSent) 
{ 
    NSMutableDictionary* currentImageMetadata = (NSMutableDictionary*)[imagesMetadata objectAtIndex:iteration]; 

    [uploadMessage setObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys: 

    [ToBase64(currentEntry,currentImageMetadata) copy],@"image_data", //here I got an exception 
    [currentImageMetadata objectForKey:@"extension"], @"extension", 
           [currentImageMetadata objectForKey:@"image_name" ], @"image_name", image_size, @"size", nil] 

    forKey:[NSString stringWithFormat:@"image%d",iteration]]; 
    iteration++; 
} 
+3

Tutto questo è letteralmente in un unico metodo? Quindi il blocco viene creato localmente prima di chiamarlo? O hai copiato/incollato il codice da diversi metodi? Inoltre, tieni presente che 'image_size' deve essere inserito in un NSNumber prima di aggiungerlo al dizionario. Con un nuovo compilatore, puoi farlo con '@ (image_size)'. –

+0

@FirozeLafeer: sembra la risposta al problema! –

+0

@FirozeLafeer ha la risposta giusta – Danilo

risposta

4

NSDictionary si aspetta che le sue chiavi e valori siano puntatori agli oggetti Objective-C. Quello che hai in image_size è un NSUInteger, che è un tipo primitivo (non firmato lungo).

Quindi, per memorizzare un valore di un tipo primitivo in un NSDictionary, è necessario inserirlo in un NSNumber o NSValue. Con versioni più recenti di LLVM, che è l'espressione semplice:

@(image_size) // this will give you an NSNumber *

Oppure, se si dispone di un compilatore vecchio allora qualcosa di simile:

[NSNumber numberWithUnsignedLong:image_size]

Speranza che aiuta.

BTW, non sono sicuro dell'uso di un blocco in questo caso. Sembra che la motivazione fosse avere una variabile __block come l'equivalente di un parametro out e niente di più? Si potrebbe prendere in considerazione solo la creazione di una funzione o un metodo separato che prende uno NSUInteger * come parametro esterno. Non il problema immediato qui, ma qualcosa da considerare per pulire un po 'questo.

+0

Tnanks uomo! Bella risposta. Mi hai davvero aiutato. Potrebbe per favore darmi un riferimento dove posso leggere di più sulla nuova sintassi di boxe: @ (image_size). Non ne ho sentito parlare. – MainstreamDeveloper00

+0

@HarryCater, ecco il documento sulle espressioni in scatola e altre modifiche correlate: http://clang.llvm.org/docs/ObjectiveCLiterals.html –

-1

E 'difficile essere completamente sicuri, ma ciò che si dovrebbe provare a fare è localizza tutte le variabili. A volte ARC non fa riferimento al conteggio di una variabile se si utilizza la stessa variabile in più metodi. Ho avuto un problema simile a questo una volta e ho localizzato tutte le variabili e ha fermato EXC_BAD_ACCESS. Spero di aver aiutato.

+2

Di cosa stai parlando? Il runtime ObjC gestisce tutto ciò che può essere inviato a conservare e rilasciare, e non è '__unsafe_unretained'. ARC non "dimentica di gestire" qualsiasi cosa sia ragionevolmente definita. Il fatto che la vita di una variabile sia stata inaspettata è colpa tua. – CodaFi

Problemi correlati