Не вдається використати respontsToSelector за допомогою ARC на Mac


83

Коли я телефоную respondsToSelectorв середовищі ARC, я отримую таке повідомлення про помилкуAutomatic Reference Counting Issue No known instance method for selector respondsToSelector:

Це заголовок

#import <AppKit/AppKit.h>


@class MTScrollView;

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


@interface MTScrollView : NSScrollView 
{

}

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

@end

Це файл реалізації

#import "MTScrollView.h"

@implementation MTScrollView

@synthesize delegate;


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

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

@end

Будь-які пропозиції щодо того, чому я отримую цю помилку?

Відповіді:


276

Зробіть протокол відповідним NSObject

@protocol MTScrollViewDelegate <NSObject>

В іншому випадку компілятор не думає, що об'єкт реагуватиме на повідомлення NSObject типу respondsToSelector, і генерує попередження. Це буде успішним під час виконання без проблем.


2
@piobyz, respondsToSelectorє методом екземпляра, NSObjectтому система повинна знати, що делегат є частиною підкласуNSObject
Девід

1
@David спасибі, ви маєте рацію, крім того , тут є ще інформація: stackoverflow.com/questions/1304176 / ...
Петро Byzia

2
@piobyz у "старому світі" до ARC компілятор припускав, що ви знаєте, що робите, і просто ігнорував деякі речі під час компіляції. Тепер ARC управляє збереженнями та випусками для вас. Щоб забезпечити існування методів, метод потрібно знайти у вашому проекті. Під час роботи з id компілятор не може знайти жодних символів. Обмежуючи протокол до NSObject, ARC точно знає, що будь-який можливий делегат буде містити "respondsToSelector". Це забезпечує узгодженість, і ваше керування пам’яттю завжди буде в порядку. Класи, які не відповідають NSObject, спричинять помилку, якщо використовувати їх як делегат.
JackPearse

1
@piobyz: Оскільки respondsToSelector:є частиною протоколу NSObject. delegateВластивість оголошується id <MTScrollViewDelegate>, що говорить лише про те , що делегат відповідає на повідомлення , оголошені в цьому протоколі. Таким чином, вам потрібен цей протокол, щоб відповідати протоколу NSObject, щоб компілятор знав, що respondsToSelector:серед них.
Пітер Хосі

1
@David: Не зовсім. delegateне оголошено з назвою класу, тому клас NSObject тут не актуальний - компілятор не знає і все ще не знає, що ці дві речі пов’язані. “NSObject”, який є частиною рішення, є протоколом NSObject , оскільки саме там respondsToSelector:декларується. developer.apple.com/library/mac/documentation/Cocoa/Reference/…
Пітер Хосі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.