Obj-C,'self'时使用的实例变量未设置为'[(super或self)init ...]的结果

Jul*_*les 4 xcode cocoa-touch objective-c analyzer

我知道我不久前问了一个类似的问题,但我仍然有点不确定.同样的事情发生在几个地方.

'self'时使用的实例变量未设置为'[(super或self)init ...]的结果

一个

- (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;
}
Run Code Online (Sandbox Code Playgroud)

- (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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

对于块A,这是正确的

self = [self init]; 
if( self != nil )
{
Run Code Online (Sandbox Code Playgroud)

和B&C

- (id) initWithFrame:(CGRect)frame {
   super = [super initWithFrame:frame]
    if(super != nil)
   {
Run Code Online (Sandbox Code Playgroud)

Hot*_*cks 15

一般来说,你应该写:

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

这是因为在某些情况下init可能无法返回原始self值.

  • 你可以使用`self = [self init ...]`如果你要调用的`init ...`的版本最终执行`[super init ...]`调用,这可能就是在某些情况下.(事实上​​,如果你的`init`在库类的类别中,它几乎是强制性的.)但是你需要确保最终调用`super`版本,否则你的对象将是不完整的. (3认同)