Чем больше я об этом думаю, тем больше я согласен с тем, что это не дубликат, и на самом деле ответ очень прост, если вы говорите, что хотите, то что вы действительно хотите.
Учитывая, что вы возвращаете значения, соответствующие некоторому протоколу, создайте тип, соответствующий этому протоколу, и перенаправьте все методы протокола в упакованное значение. Затем вы можете добавить любые дополнительные свойства, которые захотите.
Например, с учетом протокола вроде:
@protocol Runnable <NSObject>
- (void)run;
@end
Вы можете создать тривиальную оболочку, например:
@interface AnyRunnable: NSObject <Runnable>
- (instancetype)initWithRunnable:(id<Runnable>)runnable;
@end
@interface AnyRunnable (Private)
@property (nonatomic, readwrite) id<Runnable> wrapped;
@end
@implementation AnyRunnable
- (instancetype)initWithRunnable:(id<Runnable>)wrapped
{
self = [super init];
if (self) {
self.wrapped = wrapped;
}
return self;
}
- (void)run {
[self.wrapped run];
}
@end
Теперь AnyRunnable
- это Runnable
, так что вы можете вернуть это из вашего метода. Это также тип, которым вы управляете, поэтому вы можете добавлять любые свойства, которые вам нравятся. Это масштабируется до любого протокола; вам просто нужно реализовать необходимые методы.
Невозможно сделать это через категорию по причинам, указанным в Почему у категорий не может быть переменных экземпляра? (Если бы было возможно добавьте свойства на основе протоколов, но не классов, тогда вы можете просто определить протокол, который соответствует вашему классу, и обойти это ограничение.)