2013-01-23 22 views
8

Tôi có một phương pháp như thế này:Cách nào đúng để đặt một ngoại lệ NSError từ bên trong một khối autoreleasepool?

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error 
{ 
    @autoreleasepool { 

      // Start processing. 

      // Find some partway through error.. 
      if (error) { 
       *error = [NSError errorWithDomain...]; 
       return NO; 
      } 

      // More processing. 
    } 
} 

này bị hỏng và bị treo, vì NSError là autoreleased, và khi sự trở lại xảy ra, hồ bơi được để ráo nước, do đó, điều mà người gọi được bây giờ là không có thật.

Tôi biết tôi có thể thiết kế lại đáng kể phương pháp để tôi thu thập tất cả các trường hợp lỗi bên ngoài khối tự động, nhưng tôi muốn biết liệu có cách xử lý đúng đối tượng lỗi trong trường hợp này hay không. Tôi không thể phân bổ/init một NSError đầu cơ bên ngoài khối pool, bởi vì các thuộc tính miền và mã là chỉ đọc (và tôi vẫn nghĩ rằng tham chiếu sẽ biến mất khi phương thức trả về).

Nó giải quyết vấn đề nếu tôi thay đổi phương pháp kê khai như sau:

- (void)processAThing:(id)thing error:(NSError * __strong *)error 

Nhưng sau đó tôi cần phải phiền phức xung quanh tại địa điểm cuộc gọi một cách không chuẩn, và điều này dường như nghiêm trọng để làm cho người gọi trả giá cho autoreleasepool nội bộ của tôi.

Mọi suy nghĩ? Cảm ơn.

+0

Thay đổi chữ ký thành '(NSError * __strong *) error' thực sự có vẻ giống như một giải pháp thay thế hợp lý cho tôi. – Poulsbo

Trả lời

7

Tôi đã gặp sự cố này. Trong trường hợp này, tôi nghĩ bạn chỉ cần khai báo một tham chiếu mạnh mới ngay trước @autoreleasepool và đặt đối số phương thức ngay sau khối @autoreleasepool từ tham chiếu tạm thời đó.

- (void)processAThing:(id)thing error:(NSError * __autoreleasing *)error { 
    __strong NSError *errOut = nil; 
    @autoreleasepool { 
    // do your stuff and set errOut instead of error 
    } 
    if (error) { 
    *error = errOut; 
    } 
} 

(gõ vào trình duyệt, không lỗi kiểm tra bởi trình biên dịch)

Đối với lợi nhuận quá sớm của bạn, tôi đoán bạn sẽ phải sử dụng một nhãn nhảy (ngay cả khi nó không đẹp).

+0

bạn không cần phải viết '__strong'. Đó là theo mặc định – newacct

+1

Có, tôi đặt nó ở đó chỉ để làm rõ. –

+0

Cảm ơn Erik. Có vẻ như không có mô hình rõ ràng nào khác để sử dụng, ngoại trừ việc giảm thiểu phạm vi của khối autorelease và thiết lập outparam bên ngoài nó. –

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