2012-12-03 44 views
13

Cập nhật: Điều này đã được sửa trong SDK iOS 6.1 DP3.Đối tượng được tạo bên trong phạm vi được deallocated ngay cả khi được sử dụng ngoài phạm vi

Tôi đã theo dõi một vụ tai nạn do sử dụng sau khi deal-deal khi xây dựng với ARC bằng cách sử dụng cấu hình bản phát hành mặc định (debug dường như hoạt động tốt). Vấn đề xảy ra khi tạo một đối tượng bên trong một if-scope với một điều kiện không liên tục, gán nó cho một biến từ bên ngoài phạm vi và sau đó chỉ tham chiếu biến bằng mảng Objective-C hoặc literals từ điển.

Đây là trường hợp tái sản xuất nhỏ tôi đã quản lý để tìm thấy:

void test(BOOL arg) 
{ 
    id obj = nil; 

    if (arg) { 
     obj = [NSObject new]; 
    } 

    // obj already deallocated here 
    @[obj]; 

    // but using NSArray works 
    //[NSArray arrayWithObject:obj]; 

    // @[obj] works if obj is referenced i.e. by NSLog print out 
    //NSLog(@"%@", obj); 
} 

int main(int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
     test(YES); 
    } 
    return 0; 
} 

Khi tôi xây dựng và chạy này với các đối tượng zombie kích hoạt tôi nhận được thông báo lỗi này:

-[NSObject retain]: message sent to deallocated instance 0x100109100 

Như tôi đã nhận xét trong mã nó hoạt động tốt nếu obj được tham chiếu theo cách khác, như với NSLog hoặc sử dụng NSArray thay thế. Tôi đã hiểu sai cách các đối tượng được phát hành với ARC và phạm vi hay đây có phải là lỗi tối ưu trong LLVM hay Clang không?

Tôi đang sử dụng Xcode 4.5.2 với phiên bản tiếng kêu 4.1 (thẻ/Apple/clang-421.11.66) (dựa trên LLVM 3.1svn). Tôi có thể tái tạo nó khi xây dựng cho x86 64 bit cho iOS mô phỏng và Mac OS X và tôi khá chắc chắn cùng một vấn đề xảy ra khi xây dựng cho ARM là vấn đề đầu tiên được tìm thấy khi chạy phát hành xây dựng trên iPhone.

Tôi đã gửi và báo cáo lỗi cho Apple và tạo một open radar report.

Điều gì, nếu có, tôi có bị thiếu không?

Cập nhật, đã làm một số thí nghiệm hơn:

Như Gabro chỉ ra trình biên dịch dịch @[] một tuyên bố [NSArray arrayWithObjects:count:] vì vậy tôi đã làm một số xét nghiệm:

// works 
id a[] = {obj}; 
[NSArray arrayWithObjects:a count:1]; 

// does not work 
const id *b = (id[]){obj}; 
[NSArray arrayWithObjects:b count:1]; 

// does not work 
[NSArray arrayWithObjects:(id[]){obj} count:1]; 

Vì vậy, tôi đoán được rằng điều này xảy ra khi kết hợp các mảng C và ARC vô danh.

+0

+1 để đăng SSCCE –

+1

theo Apple khi bạn sử dụng mảng theo nghĩa đen, trình biên dịch tạo ra '' 'id objects [] = {obj}; NSUIteger count = sizeof (đối tượng)/sizeof (id); [mảng NSArrayWithObjects: đối tượng đếm: đếm]; '' ' Tôi tự hỏi liệu có một lỗi do đi qua các mảng C chơi –

+1

Rất kỳ quặc. Tôi gọi nó là một lỗi. Tôi đã xem xét việc tháo gỡ '@ [obj]' và 'mảng {NSArray arrayWithObject: obj]' cho x86_64 với tối ưu hóa -Os theo LLVM 4.1; và trình biên dịch chèn một cuộc gọi 'obj_release' vào' obj' trước 'NSArray'. Trừ khi ai đó thông minh hơn tôi chimes, tôi sẽ gọi nó là một lỗi. – FluffulousChimp

Trả lời

1

tôi chỉ thử nghiệm đoạn mã sau cả tòa nhà cho OSX (x86 64) và iOS Simulator và tôi không thể tái tạo các lỗi

void test(BOOL arg) { 
    id obj = nil; 

    if (arg) { 
     obj = [NSObject new]; 
    } 
    @[obj]; 
    NSLog(@"Hi there"); 
} 

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     test(YES); 
    } 
    return 0; 
} 

Đoạn mã trên chỉ đơn giản in Hi there trong giao diện điều khiển và lợi nhuận.

Cấu hình của tôi giống với cấu hình của bạn: XCode 4.5.2 và phiên bản Apple clang 4.1 (thẻ/Apple/clang-421.11.66) (dựa trên LLVM 3.1svn) làm trình biên dịch.

EDIT

Tôi cũng đã cố gắng để biên dịch từ dòng lệnh (sau khi thêm #include <Foundation/Foundation.h> vào đầu ví dụ trên) sử dụng

clang -fobjc-arc -framework Foundation main.m 

Và kết quả là một lần nữa

2012-12-03 12:47:45.647 a.out[39421:707] Hi there 

CHỈNH SỬA 2 Như chỉ ra trong các ý kiến ​​có thể sao chép các lỗi tăng mức tối ưu hóa trên -O0. Tóm tắt:

clang -O0 -fobjc-arc -framework Foundation main.m 

chương trình hoạt động như mong đợi

clang -O1 -fobjc-arc -framework Foundation main.m 

lỗi thể hiện trong câu hỏi xuất hiện. Điều này đúng với bất kỳ mức tối ưu hóa nào trên -O0

Đó chắc chắn là lỗi trong trình biên dịch.

+0

Thật kỳ lạ. Và bạn chắc chắn biên dịch của bạn với ARC? –

+1

Cấp độ tối ưu hóa nào? Tôi ** có thể ** sao chép vấn đề của OP với bất kỳ mức tối ưu hóa nào ở trên '-O0'. Không có tối ưu hóa, trình biên dịch xuất hiện không để phát hành quá mức 'obj' - nếu không nó sẽ làm. – FluffulousChimp

+0

Ah xin lỗi bây giờ tôi thấy '-fobj-arc'. Yepp ví dụ của bạn làm việc cho tôi cũng nhưng nếu tôi thêm '-Os' làm cấu hình xây dựng bản phát hành iOS mặc định thì có vẻ như nó đã được phát hành. –

1

Bạn không thiếu gì cả. Đó là một lỗi trình biên dịch.

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