2011-08-12 17 views
19

Tôi đang viết một lớp nút đơn giản, một cái gì đó như thế này:Tôi đang viết một lớp Button trong Objective-C với ARC - Làm thế nào để ngăn chặn cảnh báo rò rỉ bộ nhớ của Clang trên bộ chọn?

@interface MyButton : NSObject { 
    id object; 
    SEL action; 
} 
@property(strong) id object; 
@property SEL action; 
-(void)fire; 
@end 


@implementation MyButton 

@synthesize object, action; 

-(void)fire { 
    [object performSelector:action]; 
} 

@end 

tôi nhận được cảnh báo sau đây từ Clang trên [object performSelector:action]:

PerformSelector may cause a leak because its selector is unknown 

Sau some research Tôi thấy rằng selectors có thể thuộc về gia đình mà có các yêu cầu về bộ nhớ khác nhau. Mục đích là để hành động trả lại khoảng trống, do đó, nó không được gây ra bất kỳ sự cố ARC nào và phải phù hợp với họ trong gia đình none.

Dường như mảnh có liên quan của mã Preprocessor tôi muốn là, hoặc là một biến thể của:

__attribute__((objc_method_family(none))) 

Nhưng nơi nào tôi đặt đó để nói Clang không phải lo lắng?

+1

câu hỏi tương tự [ở đây] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is- không rõ) – zpasternack

+1

Nó thực sự là một lớp gốc? –

+0

Mặt lớp gốc là bản sao chép và chỉnh sửa lỗi đánh máy. –

Trả lời

9

Trong trình biên dịch LLVM 3,0 trong Xcode 4.2 bạn có thể ngăn chặn các cảnh báo như sau:

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
    [object performSelector:action]; 
#pragma clang diagnostic pop 

Cảm ơn đến Scott Thompson (về câu hỏi tương tự này: performSelector may cause a leak because its selector is unknown) cho câu trả lời.

5

Nếu bạn đang viết mã mới, cách tốt nhất để xử lý cuộc gọi lại là sử dụng các khối; chúng an toàn hơn và linh hoạt hơn performSelector. Xem http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html.

+1

Đây là cách tiếp cận mà tôi đã kết thúc vì lý do thực dụng, nhưng tôi sẽ giữ câu hỏi này mở trong trường hợp câu hỏi có câu trả lời. performSelector vẫn có vị trí của nó trong hộp công cụ, sau khi tất cả. –

17

Vì bạn đang gán động action, trình biên dịch sẽ thấy có thể bị rò rỉ với ARC. Trong tương lai, trình biên dịch LLVM có thể cho phép bạn chặn cảnh báo. Cho đến lúc đó, bạn có thể tránh cảnh báo bằng cách sử dụng thời gian chạy của objc_msgSend() thay vì -performSelector:.

Thứ nhất, nhập tiêu đề thư runtime

#import <objc/message.h>
Tiếp theo, thay thế performSelector: với objc_msgSend()

// [object performSelector:action]; 
    objc_msgSend(object, action); 
1

tôi sử dụng này:

[object tryToPerform:action with:nil]; 
Các vấn đề liên quan