gpt4 book ai didi

ios - Swift - 字典崩溃中的关闭

转载 作者:行者123 更新时间:2023-11-28 07:16:17 25 4
gpt4 key购买 nike

所以我有 objc 代码,它使用 Singleton 实例进行 ping(使用 SimplePing)并保存 ping 请求完成 block 。在 ObjC 中它看起来像这样:

@interface SimplePingClient()
{
NSMutableArray* _currentPings;
NSMutableDictionary* _currentCallbacks;
}

@end

@implementation SimplePingClient

-(id)init
{
if( self = [super init] )
{
_currentPings = [NSMutableArray new];
_currentCallbacks = [NSMutableDictionary new];
}

return self;
}

开始ping的方法:

-(void)pingHostname:(NSString*)hostName andResultCallBlock:(void(^)(NSString* latency))result
{
TSimplePing* pingClient = [TSimplePing simplePingWithHostName:hostName];
[_currentPings addObject:pingClient];
[_currentCallbacks setObject:result forKey:[NSValue valueWithNonretainedObject:pingClient]];
pingClient.delegate = self;
//some other irrelevant code
...
}

当调用 SimplePing 委托(delegate)方法时:

- (void)simplePing:(TSimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet
{
void(^callback)(NSString* latency) = [_currentCallbacks objectForKey:[NSValue valueWithNonretainedObject:pinger]];
if( callback )
{
//some irrelevant code
...
callback(@"123");//hard coded for test, irrelevant code get this value correctly ;)
[_currentCallbacks removeObjectForKey:[NSValue valueWithNonretainedObject:pinger]];
}
[_currentPings removeObject:pinger];
}

因此这段代码在 objc 上完美运行。但是,当我尝试在 Swift 中移植它时,我不断收到错误 EXC_BAD_ACCESS。为了简化示例,我只是删除了所有内容,结果证明将 Closure 存储在 Dictionary 中并立即调用它对我不起作用:

typealias callbackClosure = (String) -> ()

class SimplePingClient: NSObject
{
// MARK: variables
var _currentPings = [TSimplePing]()
var _currentCallbacks: Dictionary<String, callbackClosure> = [String: callbackClosure]()

private func ping(hostname: String, resultCallback:callbackClosure)
{
var pingClient = TSimplePing(hostName: hostname)
pingClient.delegate = self
_currentPings.append(pingClient)
_currentCallbacks[pingClient.hostName] = resultCallback

if let callback = _currentCallbacks[pingClient.hostName]
{
callback("123213")//here program CRASHES
}
}
}

正如您在代码中看到的那样,假设存在一些内存问题,我什至尝试使用主机名(它是字符串)而不是 NSValue,但事实并非如此 - 仍然崩溃。但是,此错误肯定与内存管理有关,但是我无法理解自己在做什么错。如果有人能指出我所缺少的东西,我会非常感激。

最佳答案

正如@Owen Hartnett 所建议的,我正在将解决方案从此处的答案本身移走:

好吧,又经过一个小时的调试,事实证明原因很愚蠢。正如我所说,我正在移植我的代码,所以之前我使用这个类作为桥接的 objective-c 代码,因此这个函数:

-(void)pingHostname:(NSString*)hostName andResultCallBlock:(void(^)(NSString* latency))result

桥接方式如下:

SimplePingClient.pingHostname(latencyUrl, refreshTime: refreshRate) { (latency: String!) -> () in

if nil != latency
{
//dummy code
}

}

因此在 SimplePingClient 成为 swift 类之后,我的新闭包签名是(注意现在延迟不是强制解包并且不是可选的,也不需要检查 nil)

SimplePingClient.pingHostname(latencyUrl, refreshTime: refreshRate) { (latency: String) -> () in

//dummy code

}

因此,通过简单地更改方法调用,一切都开始工作了。奇怪的是编译器没有注意到这个问题。

关于ios - Swift - 字典崩溃中的关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25912670/

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