我正在使用像“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:.
答案 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>,编译器会给您与上述问题相同的错误,而不会告诉您更改返回类型。