无法从init系列中的方法中分配给self?

时间:2013-04-15 10:45:13

标签: ios objective-c

我正在使用像“self = [super init];”这样的自我,以下代码给我一个错误“cannot assign to self out of a method in the init family

- (id)showDropDown:(UIButton *)b:(CGFloat *)height:(NSArray *)arr:(NSString *)direction {
    btnSender = b;
    animationDirection = direction;
    self = [super init];
    if (self) {
        // Initialization code
        CGRect btn = b.frame;
        self.list = [NSArray arrayWithArray:arr];

        if ([direction isEqualToString:@"up"]) {
            self.frame = CGRectMake(btn.origin.x, btn.origin.y, btn.size.width, 0);
            self.layer.shadowOffset = CGSizeMake(-5, -5);
        }else if ([direction isEqualToString:@"down"]) {
            self.frame = CGRectMake(btn.origin.x, btn.origin.y+btn.size.height, btn.size.width, 0);
            self.layer.shadowOffset = CGSizeMake(-5, 5);
        }

        self.layer.masksToBounds = NO;
        self.layer.cornerRadius = 8;
        self.layer.shadowRadius = 5;
        self.layer.shadowOpacity = 0.5;

        table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, btn.size.width, 0)];
        table.delegate = self;
        table.dataSource = self;
        table.layer.cornerRadius = 5;
        table.backgroundColor = [UIColor colorWithRed:0.239 green:0.239 blue:0.239 alpha:1];
        table.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
        table.separatorColor = [UIColor grayColor];

        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.5];
        if ([direction isEqualToString:@"up"]) {
            self.frame = CGRectMake(btn.origin.x, btn.origin.y-*height, btn.size.width, *height);
        } else if([direction isEqualToString:@"down"]) {
            self.frame = CGRectMake(btn.origin.x, btn.origin.y+btn.size.height, btn.size.width, *height);
        }
        table.frame = CGRectMake(0, 0, btn.size.width, *height);
        [UIView commitAnimations];

        [b.superview addSubview:self];
        [self addSubview:table];
    }
    return self;
}

错误:

 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Requesting the window of a view (<NIDropDown: 0x684ac50; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; alpha = 0; opaque = NO; layer = (null)>) with a nil layer. This view probably hasn't received initWithFrame: or initWithCoder:.

5 个答案:

答案 0 :(得分:60)

如果您的方法是初始化程序,则必须以init开头:

- (instancetype)initWithDropDown:(UIButton *)b:(CGFloat *)height:(NSArray *)arr:(NSString *)direction

否则,您可以将其更改为类方法,并返回一个新实例:

+ (instancetype)showDropDown:(UIButton *)b:(CGFloat *)height:(NSArray *)arr:(NSString *)direction
{
    btnSender = b;
    animationDirection = direction;
    YourClassName obj = [[self alloc] init];
    if (obj) {
        // Initialization code
        // …
    }
    return obj;
}

答案 1 :(得分:5)

由于以下convention,您无法在self方法之外初始化init

  

如果一个对象的类没有实现初始化器,那么   Objective-C运行时调用最近的祖先的初始值设定项   代替。

并且因为某些方法的名称被运行时的内存管理系统识别:

  

当方法名称以alloc init开头,保留或复制时   意味着它是为负责的呼叫者创建的   完成后释放对象。否则方法   返回不归呼叫者所有,他必须表明他想要   保持它在对象上调用保留。

因此,所有初始值设定项都应该写成以下变体:

- (id) init {
    self = [super init];
    if (self){
        _someVariable = @"someValue";
    }
    return self;
}
  • 不要使用if ((self = [super init])),因为它太丑了。
  • 不要使用self.someVariable,因为该对象可能尚未初始化。请改为使用直接变量访问(_someVariable)。
  • 我们写self = [super init]而不只是[super init],因为可能会返回不同的实例。
  • 我们写if (self)因为会有返回nil的情况。

但是,您的方法还有两个问题:

  • 您正在将对象创建([super init])和操作(-showDropDown::::)组合在同一方法中。你应该写两个单独的方法。
  • 您的方法名称为-showDropDown::::。 Objective-C程序员期望自我记录方法名称,如-showDropDown:height:array:direction:。我猜你来自不同的语言,但在罗马时,就像罗马人一样,否则你就不会和团队的其他成员一起玩。

答案 2 :(得分:2)

检查此方法中的拼写

newGirlFile = open('/Users/MacUser/Documents/Python/GirlNamesSorted.txt','r')
out_file = open('/Users/MacUser/Documents/Python/GirlNamesSortedOutput.txt', 'w')

girlList = []

for i in newGirlFile:
    j = i.rstrip("\r\n")
    girlList.append(j)
    girlList.sort(key=str.lower)

out_file.write("\n".join(girlList))

newGirlFile.close()
out_file.close()

代码:(Objective-C)

-(id)initwithArray:(NSArray *)array  

答案 3 :(得分:1)

我认为您必须将初始值设定项(当前名为showDropDown)重命名为以init开头的内容(如initWithDropDown…)。这曾经只是一个惯例(虽然是合理的),但现在使用ARC这是一个很难的要求。

答案 4 :(得分:0)

以防万一有人犯了类似我的错误,这可能会有所帮助。请将-(void)更改为-(id)。您需要确保返回的是id。如果您对初始化器的声明和定义同时使用-(void), strong>,编译器会给您与上述问题相同的错误,而不会告诉您更改返回类型。