2013-07-06 29 views
6

Tôi đang viết một ứng dụng mà tôi cần gửi các hình ảnh PNGJPG tới máy chủ. Mã để chuyển đổi hình ảnh JPEG/PNG thành chuỗi Base64 tôi đã viết dưới dạng khối Obj-C. Nhưng khi tôi cố gắng thêm chuỗi được trả về theo khối đến NSDictionary Tôi nhận được code=EXC_ARM_DA_ALIGN. Trong dự án của tôi, tôi sử dụng ARC. Tôi đã đọc một số bài viết về vấn đề này ARC: EXC_BAD_ACCESS when calling a method from inside a block, inside a delegate method Vì vậy, tôi sử dụng copy! Nhưng nó đã không giúp tôi. Trước khi tôi sử dụng copy tôi đã nhận EXC_BAD_EXCEPTION với mã = ​​1 và bây giờ với mã trên tiêu đề. Đây là mã của tôi:Tại sao tôi có EXC_BAD_ACCESS_EXCEPTION (code = EXC_ARM_DA_ALIGN) khi sử dụng khối với 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

Đây có phải là tất cả nghĩa đen trong một phương pháp không? Vì vậy, các khối được tạo ra tại địa phương ngay trước khi bạn gọi nó? Hay bạn đã sao chép/dán mã từ các phương thức khác nhau? Ngoài ra, xin lưu ý rằng 'image_size' cần được đóng hộp trong NSNumber trước khi bạn thêm nó vào từ điển. Với trình biên dịch mới, bạn có thể thực hiện điều này bằng '@ (image_size)'. –

+0

@ FirozeLafeer: Có vẻ như câu trả lời cho vấn đề! –

+0

@FirozeLafeer có câu trả lời đúng – Danilo

Trả lời

4

NSDictionary mong đợi các khóa và giá trị của nó là con trỏ đến đối tượng Objective-C. Những gì bạn có trong image_size là một NSUInteger, là một kiểu nguyên thủy (unsigned long).

Vì vậy, để lưu trữ một giá trị của một loại nguyên thủy trong một NSDictionary bạn phải bọc nó trong một NSNumber hoặc NSValue. Với phiên bản mới hơn của LLVM, đó là một biểu thức đơn giản:

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

Hoặc nếu bạn có một trình biên dịch cũ sau đó một cái gì đó như thế này:

[NSNumber numberWithUnsignedLong:image_size]

Hy vọng rằng sẽ giúp.

BTW, tôi không chắc về việc sử dụng khối trong trường hợp này. Có vẻ như động lực là có một biến __block tương đương với tham số ngoài và không có gì hơn? Bạn có thể xem xét chỉ cần làm cho rằng một chức năng riêng biệt hoặc phương pháp đó có một NSUInteger * như một tham số ra. Không phải là vấn đề ngay lập tức ở đây, nhưng một cái gì đó để xem xét để làm sạch này lên một chút.

+0

Tnanks man! Câu trả lời chính xác. Bạn thực sự đã giúp tôi. Bạn có thể vui lòng cho tôi một tài liệu tham khảo để tôi có thể đọc thêm về cú pháp boxing mới không: @ (image_size) .Tôi không nghe về nó. – MainstreamDeveloper00

+0

@HarryCater, đây là tài liệu về các biểu thức được đóng hộp và các thay đổi có liên quan khác: http://clang.llvm.org/docs/ObjectiveCLiterals.html –

-1

Thật khó để hoàn toàn chắc chắn, nhưng những gì bạn nên thử làm là bản địa hóa tất cả các biến của bạn. Đôi khi, ARC không tính số tham chiếu cho một biến nếu bạn đang sử dụng cùng một biến trong nhiều phương thức. Tôi đã có một vấn đề tương tự như thế này một lần và tôi đã bản địa hoá tất cả các biến và nó dừng EXC_BAD_ACCESS. Hy vọng tôi đã giúp.

+2

Bạn đang nói về cái gì? Thời gian chạy ObjC mang tất cả mọi thứ có thể được gửi và giữ lại, và không phải là '__unsafe_unretained'. ARC không "quên quản lý" bất cứ điều gì được xác định hợp lý. Thực tế là cuộc đời của một biến là bất ngờ là lỗi của riêng bạn. – CodaFi

Các vấn đề liên quan