initWithData: ожидаемая структура NSData * предупреждение

#objective-c #cocoa-touch #ios

#objective-c #cocoa-touch #iOS

Вопрос:

Я получаю странное предупреждение с помощью моего метода initWithData::

предупреждение: несовместимые типы Objective-C ‘struct NSDictionary *’, ожидаемые ‘struct NSData *’ при передаче аргумента 1 ‘initWithData:’ из другого типа Objective-C.

в TRDevice.h:

 @interface TRDevice : NSObject
{
    NSString *name;      
}

@property (nonatomic, copy) NSString *name;

-(id)initWithData:(NSDictionary *)inData;

@end
  

в TRDevice.m:

 - (id)initWithData:(NSDictionary *)inData
{
    if ((self = [super init]))
    {
        self.name = [inData valueForKey:TRDeviceNameKey];
    }
    return self;
}
  

И где я пытаюсь создать экземпляр вышеупомянутого объекта:

 NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSArray *dataArray = [prefs arrayForKey:TRDevicesKey];
for (NSDictionary *data in dataArray)
{
    TRDevice *device = [[TRDevice alloc] initWithData:data];
    [self.devices addObject:device];
    [device release];
}
  

Это предупреждение исчезнет, если я 1) переименую метод init во что-то другое, например initWithDictionary: . или 2) если я передам nil в initWithData: .

AFAIK NSObject не реализует метод initWithData:, поэтому я также не переопределяю его. Я понятия не имею, почему я получаю это предупреждение.

Ответ №1:

alloc не возвращает NSObject , он возвращает id . это правильное объявление. тип (с точки зрения компилятора) стирается, когда он возвращается через (id)alloc .

большинство применений initWithData: принимают NSData в качестве своего первого аргумента. это одна из причин, по которой objc «так хорошо читается» и является описательным.

в любом случае … лично я бы просто переименовал его в initWithDictionary: для ясности, условности и чтобы избежать предупреждения.

другой вариант — просто объявить ваш инициализатор, чтобы включить тип:

 - (id)initTRDeviceWithData:(NSDictionary *)data;
  

это достаточно подробно, чтобы не конфликтовать с другими классами в переводе.

или вы можете объявить удобный конструктор:

   (TRDevice *)newTRDeviceWithData:(NSDictionary *)data;
  

или вариант для автоматически выпущенного типа:

   (TRDevice *)trDeviceWithData:(NSDictionary *)data; // eww...