我正在实现键值验证,如下所示:
- (BOOL)validateValue:(__autoreleasing id *)value forKey:(NSString *)key error:(NSError *__autoreleasing *)error
{
NSAttributeDescription *attribute = [[self.entity attributesByName] objectForKey:key];
if (attribute && attribute.attributeType == NSStringAttributeType) {
*value = [NSString stringWithFormat:@"%@ modified", *value];
return YES;
}
return [super validateValue:value forKey:key error:error];
}
当它运行时,内存会不断增加,直到应用程序收到内存警告并在 250 MB 标记处崩溃。
有趣的是,通过以下变化,总内存占用保持稳定在 5 MB 左右。
*value = [NSString stringWithFormat:@"%@", *value];
*value = [NSString stringWithFormat:@"%@ modified", NSStringFromClass([self class])];
对于第一个变体,我怀疑 +stringWithFormat 被优化为简单地返回 *value 不变。
第二个变体只是我试图确保编译器或目标 c 运行时不会返回已经存在的对象而不分配任何新对象。
只有当我创建一个包含传入值的新字符串对象时,内存才会增加。
我试过做
NSString * __unsafe_unretained tmp = *value;
*value = [NSString stringWithFormat:@"%@ modified", tmp];
CFStringRef tmp = (__bridge_retained CFStringRef)*value;
*value = [NSString stringWithFormat:@"%@ modified", tmp];
CFRelease(tmp);
无济于事。
我究竟做错了什么?