这个autoRelease用法有什么问题吗?

时间:2012-12-26 19:46:05

标签: ios uilabel autorelease

或者替代方案:这个UILabel用法怎么可能生成NSMutableDictionary NSInvalidArgumentException?

这是一款非ARC iOS应用。当showLabel(下面)运行时,我偶尔会看到[__NSDictionaryM setObject:forKey:]抛出一个错误:NSInvalidArgumentException * setObjectForKey:key不能为零。

@property (nonatomic, retain) UILabel *myLabel;
@synthesize myLabel = _myLabel;

- (void)showLabel{

if (self.myLabel) {
    return;
}

self.myLabel                        = [[[UILabel alloc] initWithFrame:self.tableView.frame] autorelease];
self.myLabel.textColor              = [UIColor whiteColor];
self.myLabel.shadowColor            = [UIColor blackColor];
self.myLabel.shadowOffset           = CGSizeMake(0, 1);
self.myLabel.textAlignment          = UITextAlignmentCenter;
self.myLabel.text                   = @"blah";
self.myLabel.userInteractionEnabled = YES;
[self.myLabel addGestureRecognizer:[[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTapped:)] autorelease]];
[self.view addSubview:self.myLabel];
[self.view bringSubviewToFront:self.myLabel];

}

- (void)hideLabel {
if (!self.myLabel) {
    return;
}

[self.myLabel removeFromSuperview];
self.myLabel = nil;

}

如果我打破[__NSDictionaryM setObject:forKey:],它将在UILabel的setTextColor,setShadow,setShadowOffset和setTextAlignment方法中调用。我发送的值都不应该是nil,但是这个字典用法是标签内部的,所以我想知道是否因为导致自动释放池的其他事件导致自动释放后我失去了对标签的引用当我还在我的方法中时(在应用程序中涉及多个外部库),并且由于这个原因,内部字典使用偶尔会遇到错误。

在这种情况下,这可能解释NSMutableDictionary的NSInvalidArgumentException错误吗?

这是完整的堆栈跟踪:

NSInvalidArgumentException *** setObjectForKey: key cannot be nil

1 libobjc.A.dylib 0x3678c963 objc_exception_throw + 31
2 CoreFoundation 0x378625ef -[__NSDictionaryM setObject:forKey:] + 143
3 MyApp 0x000effab -[TableViewController showLabel] (MainTableViewController.m:222)
4 CoreFoundation 0x37851349 _CFXNotificationPost + 1421
5 Foundation 0x37b2d38f -[NSNotificationCenter postNotificationName:object:userInfo:] + 71
6 MyApp 0x000d9141 -[Event setDictionary:] (Event.m:123)

1 个答案:

答案 0 :(得分:1)

我可以肯定地说它与自动释放无关。您的属性有一个保留,并且您在存储变量时正确使用该属性,因此您的保留计数器变为+1(alloc)+1(属性设置器保留)并最终为-1(自动释放)

您的问题可能在其他地方,但如果没有更多代码,我无法弄清楚,抱歉!

编辑:如果你想玩超级安全(我实际上会推荐这个),你可以这样做:

self.myLabel = [[UILabel alloc] initWithFrame:self.tableView.frame];
// configure
[self.myLabel release];

同样适合您的手势识别器

尝试一下,看看你是否还在崩溃