簡體   English   中英

不能從 init 系列中的方法中分配給 self 嗎?

[英]Cannot assign to self out of a method in the init family?

我正在使用 self 之類的“ 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:.

如果您的方法是初始化程序,則它必須以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;
}

由於以下約定,您不能在init方法之外初始化self

如果一個對象的類沒有實現初始化器,Objective-C 運行時會調用最近祖先的初始化器。

並且因為一些方法的名稱被運行時的內存管理系統識別:

當方法的名稱以 alloc init、retain 或 copy 開頭時,這意味着它是為調用者創建的,調用者有責任在完成后釋放對象。 否則返回的方法不歸調用者所有,他必須表明他希望保持它對對象調用保留。

因此,所有初始值設定項都應編寫為以下內容的變體:

- (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:這樣的自記錄方法名稱。 我猜你來自不同的語言,但在羅馬時,要像羅馬人那樣做,否則你就不會和球隊的其他人一起踢球了。

在此方法中檢查您的拼寫

-(id)initwithArray:(NSArray *)array  

代碼:(目標-C)

-(id)initWithArray:(NSArray *)array  

我認為您必須將初始化程序(當前名為showDropDown )重命名為以init開頭的名稱(例如initWithDropDown… )。 這曾經只是一個約定(盡管是一個合理的約定),但現在對於 ARC,這是一個硬性要求。

以防萬一有人犯了與我類似的錯誤,這可能會有所幫助。 請將-(void)更改為-(id) 你需要確保你返回一個id 。如果你使用-(void)聲明定義initialiser ,編譯器會給你同樣的錯誤,而不告訴你改變返回類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM