- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
static NSCharacterSet *charSet = nil;
if (!charSet) {
charSet = [[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] retain];
}
NSRange loc = [(NSString*)textField.text rangeOfCharacterFromSet:charSet];
if (loc.location != NSNotFound) {
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"error!",@"")
message:@"description."
delegate:self
cancelButtonTitle:NSLocalizedString(@"OK",@"")
otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
return NO;
}
return YES;
}
我有一个与autorelease相关的问题。
我知道当我以这种方式创建对象时:
charset =[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet];
对象是自动释放的。
我有疑问 - 为什么在这个对象上有 retain 的原因是 - 在首次调用函数后释放对象?
答案 0 :(得分:2)
这是因为charSet被声明为静态。正常范围规则适用,因此它仅在此方法中可见。但是,静态变量不会存在于堆栈中,并在方法返回时保留它们的值,因此如果再次调用它们仍然具有相同的值。这就是为什么有“if(!charSet)” - 这会检查对象是否已经创建,所以如果是这样可以重新使用现有对象。
没有-retain,NSCharacterSet对象是自动释放的,并且它所居住的内存块可以(并且将)用于其他内容。但是当发生这种情况时,指向该内存的charSet*
指针不会重置为nil。它仍然具有旧的价值;由于该值为非零,因此if(!charSet)
为false,因此不会创建新对象。但是,由于旧对象被破坏,所以没有人知道该指针引用的内存可能是什么 - 它可能是随机垃圾,它可能是其他一些对象,它可能是任何东西。