gpt4 book ai didi

iphone - ARC `BAD_ACCESS` 使用 NSString 的类别方法时

转载 作者:可可西里 更新时间:2023-11-01 03:30:50 25 4
gpt4 key购买 nike

我这样调用我的实用方法:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"dd.MM.yy HH:mm"];
NSString *dateString = [dateFormat stringFromDate:[NSDate date]];

return [[Environment sharedInstance].versionLabelFormat replaceTokensWithStrings:
@"VERSION", APP_VERSION,
@"BUILD", APP_BULD_NUMBER,
@"DATETIME" , dateString,
nil ];

这是 NSString类别法

-(NSString *)replaceTokensWithStrings:(NSString *)firstKey, ... NS_REQUIRES_NIL_TERMINATION{

NSString *result = self;

va_list _arguments;
va_start(_arguments, firstKey);

for (NSString *key = firstKey; key != nil; key = va_arg(_arguments, NSString*)) {

// The value has to be copied to prevent crashes
NSString *value = [(NSString *)(va_arg(_arguments, NSString*))copy];

if(!value){
// Every key has to have a value pair otherwise the replacement is invalid and nil is returned

NSLog(@"Premature occurence of nil. Each token must be accompanied by a value: %@", result);
return nil;
}

result = [result replaceToken:key withString:value];
}
va_end(_arguments);

// Check if there are any tokens which were not yet replaced (for example if one value was nil)

if([result rangeOfString:@"{"].location == NSNotFound){
return result;
} else {
NSLog(@"Failed to replace tokens failed string still contains tokens: %@", result);
return nil;
}
}

否 在下一行我必须添加 copy声明否则会有一个带有dateString的僵尸:

NSString *value = [(NSString *)(va_arg(_arguments, NSString*))copy];

更具体地说,僵尸报告告诉我的是:

 1 Malloc       NSDateFormatter stringForObjectValue:
Autorelease NSDateFormatter stringForObjectValue:
2 CFRetain MyClass versionString:
3 CFRetain replaceToken:withString:
2 CFRelease replaceToken:withString:
1 CFRelease replaceTokensWithStrings: ( One release too much!)
0 CFRelease MyClass versionString:
-1 Zombie GSEventRunModal

尽管 copy语句似乎解决了问题我想了解代码不符合 ARC 的原因,以便 BAD_ACCESS没有 copy 就会发生对于值字符串。

最佳答案

正如其他人所说,问题在于您从可能与 ARC 不兼容的可变参数列表中检索对象的方式。

va_arg 有一种有趣的方式来返回 ARC 可能不知道的特定类型的值。我不确定这是 clang 中的错误还是 ARC 的预期行为。我会澄清这个问题并相应地更新帖子。

作为解决方法,只需在参数处理中使用 void 指针并以 ARC 安全方式将它们正确转换为对象即可避免此问题:

for (NSString *key = firstKey; key != nil; key = (__bridge NSString *)va_arg(_arguments, void *)) {
NSString *value = (__bridge NSString *)va_arg(_arguments, void *);
NSAssert(value != NULL, @"Premature occurence of nil.");
result = [result stringByReplacingToken:key
withString:value];
}

编辑:__bridge 转换告诉 ARC 不要对所有权做任何事情。它只是期望对象是活着的,不会转移或放弃所有权。然而,keyvalue 变量在使用时保持对对象的强引用。

第二次编辑:似乎 clang/ARC 应该知道 va_arg 中的类型并发出警告或做正确的事情(see this, for example)。

我尝试重现您的问题,但没有成功。一切都适合我:

$ clang --version
> Apple clang version 4.0 (tags/Apple/clang-421.10.48) (based on LLVM 3.1svn)

您使用哪个 Xcode 版本?

关于iphone - ARC `BAD_ACCESS` 使用 NSString 的类别方法时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11576293/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com