Swift-사전 충돌의 클로저

hris.to

그래서 Singleton 인스턴스를 사용하여 핑 (SimplePing 사용)을 만들고 핑 요청 완료 블록을 보유하는 objc 코드가 있습니다. ObjC에서는 다음과 같습니다.

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

@end

@implementation SimplePingClient

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

    return self;
}

핑을 시작하는 방법 :

-(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 대리자 메서드가 호출되면 :

- (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 대신 호스트 이름 (문자열)을 사용하려고 시도하지만 그렇지 않습니다. 여전히 충돌합니다. 그러나이 오류는 확실히 메모리 관리와 관련이 있지만 내가 뭘 잘못하고 있는지 이해할 수 없습니다. 누구든지 내가 놓친 것을 지적 할 수 있다면 나는 그것을 정말로 평가할 것입니다.

hris.to

@Owen Hartnett가 제안했듯이 여기에 답변 자체에서 솔루션을 이동하고 있습니다.

좋아요, 한 시간 더 디버깅을 한 후에 이유가 꽤 어리석은 것으로 밝혀졌습니다. 내가 내 코드를 포팅한다고 말했듯이 이전에는이 ​​클래스를 브리지 된 목적 -c 코드로 사용 했으므로이 함수는 다음과 같습니다.

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

다음과 같은 방식으로 연결되었습니다.

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

   if nil != latency
   {
       //dummy code
   }

}

따라서 SimplePingClient가 신속한 클래스가 된 후 내 새 클로저 서명은 다음과 같습니다. (이제 대기 시간은 강제로 풀리지 않으며 선택 사항이 아니며 nil에 대해 확인할 필요가 없습니다)

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

       //dummy code

    }

그래서 단순히 메서드 호출을 변경함으로써 모든 것이 작동하기 시작했습니다. 컴파일러가이 문제를 알아 차리지 못하는 이상한 점.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Fabric 사용시 앱 충돌-Swift의 Cannonball?

분류에서Dev

Swift 2.0의 이전 값과 정의가 충돌합니다.

분류에서Dev

Parse를 사용하여 Swift의 클로저에서 값 캡처

분류에서Dev

Swift Facebook 로그인 충돌

분류에서Dev

Swift의 "some"키워드로 인한 메모리 관련 충돌

분류에서Dev

Swift 3.0의 선택적 문자열로 인한 충돌

분류에서Dev

Swift의 UIActivityViewController에서 충돌

분류에서Dev

모든 사전 키를 1로 설정하면 충돌이 발생합니다. BAD_ACCESS Swift

분류에서Dev

모든 사전 키를 1로 설정하면 충돌이 발생합니다. BAD_ACCESS Swift

분류에서Dev

함수에 전달 된 클로저를 사용하면 malloc 충돌이 발생합니다.

분류에서Dev

약 150 장의 사진을 업로드 한 후 브라우저 충돌

분류에서Dev

웹 소켓 URL과 레일의 경로 사이의 충돌

분류에서Dev

Swift Optional Unwrapped 여전히 충돌

분류에서Dev

벽돌과 공 사이의 충돌 감지 (숫자 배열로 작동)

분류에서Dev

두 클래스 간의 통신에 swift의 클로저를 사용할 수 있습니까?

분류에서Dev

정적 방법으로 객체 사이의 충돌을 확인?

분류에서Dev

사용자 정의보기로 인해 앱이 충돌 함

분류에서Dev

서로 다른 충돌 범주에 별도의 기능 사용

분류에서Dev

동영상 로딩과 <body onload> 사이의 충돌

분류에서Dev

괄호로 묶인 복수 (s) 및 (s) AutoCorrected to § 사이의 충돌

분류에서Dev

fastprogress의 버전 충돌

분류에서Dev

수백 (아마도 수천)의 충돌 검사로 잘 실행되는 Javascript 충돌 엔진?

분류에서Dev

Swift 사전의 Swift 배열

분류에서Dev

Swift에서 tableViewController 충돌로 푸시

분류에서Dev

Objective-C의 클로저 (Swift)에서 클로저 (블록?)까지

분류에서Dev

Swift에서 초기화 매개 변수로 클로저 전달

분류에서Dev

Qt Creator의 경로 충돌

분류에서Dev

Qt Creator의 경로 충돌

분류에서Dev

Objective-C 클로저로 Swift 열거 형 사용

Related 관련 기사

  1. 1

    Fabric 사용시 앱 충돌-Swift의 Cannonball?

  2. 2

    Swift 2.0의 이전 값과 정의가 충돌합니다.

  3. 3

    Parse를 사용하여 Swift의 클로저에서 값 캡처

  4. 4

    Swift Facebook 로그인 충돌

  5. 5

    Swift의 "some"키워드로 인한 메모리 관련 충돌

  6. 6

    Swift 3.0의 선택적 문자열로 인한 충돌

  7. 7

    Swift의 UIActivityViewController에서 충돌

  8. 8

    모든 사전 키를 1로 설정하면 충돌이 발생합니다. BAD_ACCESS Swift

  9. 9

    모든 사전 키를 1로 설정하면 충돌이 발생합니다. BAD_ACCESS Swift

  10. 10

    함수에 전달 된 클로저를 사용하면 malloc 충돌이 발생합니다.

  11. 11

    약 150 장의 사진을 업로드 한 후 브라우저 충돌

  12. 12

    웹 소켓 URL과 레일의 경로 사이의 충돌

  13. 13

    Swift Optional Unwrapped 여전히 충돌

  14. 14

    벽돌과 공 사이의 충돌 감지 (숫자 배열로 작동)

  15. 15

    두 클래스 간의 통신에 swift의 클로저를 사용할 수 있습니까?

  16. 16

    정적 방법으로 객체 사이의 충돌을 확인?

  17. 17

    사용자 정의보기로 인해 앱이 충돌 함

  18. 18

    서로 다른 충돌 범주에 별도의 기능 사용

  19. 19

    동영상 로딩과 <body onload> 사이의 충돌

  20. 20

    괄호로 묶인 복수 (s) 및 (s) AutoCorrected to § 사이의 충돌

  21. 21

    fastprogress의 버전 충돌

  22. 22

    수백 (아마도 수천)의 충돌 검사로 잘 실행되는 Javascript 충돌 엔진?

  23. 23

    Swift 사전의 Swift 배열

  24. 24

    Swift에서 tableViewController 충돌로 푸시

  25. 25

    Objective-C의 클로저 (Swift)에서 클로저 (블록?)까지

  26. 26

    Swift에서 초기화 매개 변수로 클로저 전달

  27. 27

    Qt Creator의 경로 충돌

  28. 28

    Qt Creator의 경로 충돌

  29. 29

    Objective-C 클로저로 Swift 열거 형 사용

뜨겁다태그

보관