Không thể sử dụng responseToSelector bằng ARC trên Mac


83

Khi tôi gọi respondsToSelectortrong môi trường ARC, tôi nhận được thông báo lỗi sauAutomatic Reference Counting Issue No known instance method for selector respondsToSelector:

Đây là tiêu đề

#import <AppKit/AppKit.h>


@class MTScrollView;

@protocol MTScrollViewDelegate
-(void)scrollViewDidScroll:(MTScrollView *)scrollView;
@end


@interface MTScrollView : NSScrollView 
{

}

@property(nonatomic, weak) id<MTScrollViewDelegate>delegate;

@end

Đây là tệp triển khai

#import "MTScrollView.h"

@implementation MTScrollView

@synthesize delegate;


- (void)reflectScrolledClipView:(NSClipView *)aClipView
{
    [super reflectScrolledClipView:aClipView];

    if([delegate respondsToSelector:@selector(scrollViewDidScroll:)])
    {
        [delegate scrollViewDidScroll:self];
    }
}

@end

Bất kỳ đề xuất nào về lý do tại sao tôi gặp lỗi này?

Câu trả lời:


276

Làm cho giao thức phù hợp với NSObject

@protocol MTScrollViewDelegate <NSObject>

Nếu không, trình biên dịch sẽ không nghĩ rằng đối tượng sẽ trả lời các thông báo NSObject như respondsToSelector, và sẽ tạo ra một cảnh báo. Nó sẽ thành công trong thời gian chạy mà không có vấn đề gì cả.


2
@piobyz, respondsToSelectorlà một phương pháp thể hiện của NSObjectquá nhu cầu hệ thống để biết rằng các đại biểu là một số lớp con củaNSObject
David

1
@ David cảm ơn, bạn nói đúng, bổ sung ở đây là một số thông tin thêm: stackoverflow.com/questions/1304176/...
Piotr Byzia

2
@piobyz trong "thế giới cũ" trước ARC trình biên dịch cho rằng bạn biết mình đang làm gì và chỉ đơn giản là bỏ qua một số nội dung tại thời điểm biên dịch. Bây giờ ARC quản lý việc giữ lại và phát hành cho bạn. Để có thể đảm bảo rằng một phương thức tồn tại, phương thức đó phải được tìm thấy trong dự án của bạn. Trong khi làm việc với id, trình biên dịch không thể tìm thấy bất kỳ ký hiệu nào. Bằng cách hạn chế giao thức đối với NSObject, ARC biết chính xác rằng bất kỳ đại biểu nào có thể sẽ chứa "responseToSelector". Điều này đảm bảo tính nhất quán và việc quản lý bộ nhớ của bạn sẽ luôn ổn. Các lớp không phù hợp với NSObject sẽ gây ra lỗi nếu được sử dụng làm đại biểu.
JackPearse

1
@piobyz: Vì respondsToSelector:là một phần của giao thức NSObject. Cácdelegate tài sản được khai báo là id <MTScrollViewDelegate>, mà nói duy nhất mà chúng phản ứng đại biểu để thông điệp khai báo trong giao thức đó. Do đó, bạn cần giao thức đó tuân theo giao thức NSObject để trình biên dịch biết rằng giao thức đó respondsToSelector:nằm trong số đó.
Peter Hosey

1
@David: Không hoàn toàn. delegatekhông được khai báo với tên lớp, vì vậy lớp NSObject không liên quan ở đây — trình biên dịch không, và vẫn không, biết rằng hai thứ đó có liên quan với nhau. “NSObject” là một phần của giải pháp là giao thức NSObject , vì đó là nơi respondsToSelector:được khai báo. developer.apple.com/library/mac/documentation/Cocoa/Reference/…
Peter Hosey

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.