[英]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.