我使用自己像" 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;
}
Run Code Online (Sandbox Code Playgroud)
错误:
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:.
Run Code Online (Sandbox Code Playgroud)
Mar*_*bri 61
如果您的方法是初始化程序,则必须以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;
}
Run Code Online (Sandbox Code Playgroud)
由于以下约定,您无法self在init方法外部进行初始化:
如果对象的类没有实现初始化程序,则Objective-C运行时会调用最近的祖先的初始化程序.
并且因为某些方法的名称被运行时的内存管理系统识别:
当方法的名称以alloc init,retain或copy开头时,它意味着它是为调用者创建的,调用者有责任在完成对象时释放该对象.否则返回的方法不归调用者所有,并且他必须表明他希望保持对对象调用retain.
因此,所有初始化程序都应该写成以下变体:
- (id) init {
self = [super init];
if (self){
_someVariable = @"someValue";
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
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:.我猜你来自不同的语言,但是在罗马时,就像罗马人一样,或者你不会和团队的其他成员一起玩.| 归档时间: |
|
| 查看次数: |
18814 次 |
| 最近记录: |