Obj-C, переменная экземпляра, используемая при ‘self’, не установлена на результат ‘[(super или self) инициализации …]’

#objective-c #xcode #cocoa-touch #analyzer

#objective-c #xcode #cocoa-touch #анализатор

Вопрос:

Я знаю, что не так давно задавал аналогичный вопрос этому, но я все еще немного не уверен в этом. То же самое происходит в нескольких местах.

Переменная экземпляра, используемая при ‘self’, не установлена на результат ‘[(super или self) инициализации …]’

A

 - (id)initWithCoder:(NSCoder *)decoder {
  if (![super init]) return nil;
  red = [decoder decodeFloatForKey:kRedKey];  //occurs here
  green = [decoder decodeFloatForKey:kGreenKey];
  blue = [decoder decodeFloatForKey:kBlueKey];
  return self;
}
  

B

 - (id)initWithFrame:(CGRect)frame title:(NSString*)str sideUp:(BOOL)up{

    if(![super initWithFrame:frame]) return nil;

    int y;
    UIImage *img;

    if(up){
        img = [UIImage imageNamedTK:@"TapkuLibrary.bundle/Images/graph/popup"];
        y = 5;
    }else{
        img = [UIImage imageNamedTK:@"TapkuLibrary.bundle/Images/graph/popdown"];
        y = 14;
    }

    background = [[UIImageView alloc] initWithImage:img]; // occurs here
  

C

  - (id) initWithFrame:(CGRect)frame {
    if(![super initWithFrame:frame]) return nil;

    UILabel *titleBackground = [[[UILabel alloc] initWithFrame:
            CGRectMake(0, 0, 480, 40)] autorelease];
    titleBackground.backgroundColor = [UIColor whiteColor];
    [self addSubview:titleBackground];

    titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; // occurs here
  

Для блока A это правильно

 self = [self init]; 
if( self != nil )
{
  

И B amp; C

 - (id) initWithFrame:(CGRect)frame {
   super = [super initWithFrame:frame]
    if(super != nil)
   {
  

Комментарии:

1. это вопрос? и если да, то в чем заключается вопрос?

2. если вы пишете подкласс, используйте super

Ответ №1:

Как правило, вы должны написать:

 self = [super init...];  // Potentially change "self"
if (self) {
    something = x;
    another = y;
}
return self;
  

Это связано с тем, что в некоторых случаях init может не возвращаться исходное self значение.

Комментарии:

1. Спасибо за ваш четкий ответ, не содержащий технических деталей… почему self =[super и нет self = [self ?

2. Вы можете использовать, self = [self init...] если init... вызов, который вы будете вызывать, в конечном итоге выполнит [super init...] вызов, и это может быть то, что нужно делать в некоторых случаях. (На самом деле, это в значительной степени обязательно, если ваш init находится в категории библиотечного класса.) Но вы должны быть уверены, что super версия будет вызвана в конечном итоге, иначе ваш объект будет неполным.