GCD阻止samplePing的响应

时间:2014-11-19 20:48:36

标签: ios grand-central-dispatch

我在wifi网络范围内ping所有可用的IPS,如下所示:

for (int i=0; i < Range; i++) {
    [SimplePingHelper ping:strIps[i]];
}

可以想象这个活动需要相当长的时间,因此我想在后台运行它。上面的代码段是我将在下面发布的更大方法的一部分。我已经完成了多个调试器会话,我注意到的一件事是,当我调用扫描方法时(见下文),samplePing(直接来自苹果)无法到达

static void HostResolveCallback(CFHostRef theHost, 
                                CFHostInfoType typeInfo, 
                                const CFStreamError *error, 
                                void *info)

如果未达到此方法,则不会加载arp表,并且我的应用程序不再有效。

以下是我如何调用GCD:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0 ), ^{
    [self scanWifi];
});

这是scanWifi方法:

-(void)scanWifi{
    WifiInfo *wi = [[WifiInfo alloc] init];
    NSString *phoneIp = [wi getIPAddress:true];
    NSString *maxIp = [wi getBroadcastIp:phoneIp];
    NSString *minIp = [wi getMinIp:phoneIp];

    unsigned long ULmaxIp = [wi StrIp2UnsignedLong:maxIp];
    unsigned long ULminIp = [wi StrIp2UnsignedLong:minIp];
    ULmaxIp --;
    ULminIp ++;

    unsigned long iterateIp = ULminIp;
    unsigned long Range = ULmaxIp - ULminIp;


    NSString *strIps [Range];

    for (int i = 0; i < Range; i++) {
        strIps[i] = [wi unsignedInt2StrIp:iterateIp];
        iterateIp ++;
    }


    for (int i=0; i < Range; i++) {
        //I am using a simplePingHelper to handle management of the SamplePing
        [SimplePingHelper ping:strIps[i]];
    }

    ip2mac *i2m = [[ip2mac alloc] init];


    for (int i = 0; i < Range; i++) {
        //convert the ip to a char string
        char *chIp = (char *)[strIps[i] UTF8String];
        //use the char string to look into arp table
        NSString *mac = [[i2m Stip2mac:chIp]uppercaseString];

        //this is the mac prefix I want
        if([mac hasPrefix:@"60:CB:FB"]) {

            //check device exists
            if ([self deviceExist]) {
                //update device that already exists in core data
                [self updateToCoreData:@"AirScapeFan" :strIps[i] :mac :@"ssid"];
            }else{
                //add new device to core data
                [self saveToCoreData:@"AirScapeFan" :strIps[i] :mac :@"ssid"];
            }
            //Method to call up all entries in core data and print them
            [self printFromCoreData];
        }        
    }
}

只是为了踢:这是我稍微修改过的SimplePingHelper代码:

//
//  SimplePingHelper.m
//  PingTester
//
//  Created by Chris Hulbert on 18/01/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "SimplePingHelper.h"

@interface SimplePingHelper()

@property(nonatomic,retain) SimplePing* simplePing;

- (id)initWithAddress:(NSString*)address;
- (void)go;

@end

@implementation SimplePingHelper
@synthesize simplePing;

#pragma mark - Run it

// Pings the address, and calls the selector when done. Selector must take a NSnumber which is a bool for success
+ (void)ping:(NSString*)address {
    // The helper retains itself through the timeout function
    [[[SimplePingHelper alloc] initWithAddress:address] go];
}

#pragma mark - Init/dealloc

- (void)dealloc {
    self.simplePing = nil;
}

- (id)initWithAddress:(NSString*)address {
    if (self = [self init]) {
        self.simplePing = [SimplePing simplePingWithHostName:address];
        self.simplePing.delegate = self;
  }
 return self;
}

#pragma mark - Go

- (void)go {
    [self.simplePing start];
    [self performSelector:@selector(endTime) withObject:nil afterDelay:1]; // This timeout is what retains the ping helper
}

#pragma mark - Finishing and timing out

// Called on success or failure to clean up
- (void)killPing {
   [self.simplePing stop]; // In case, higher up the call stack, this got called by the simpleping object itself
   self.simplePing = nil;
}

- (void)successPing {
    [self killPing];

}

- (void)failPing:(NSString*)reason {
    [self killPing];
}

// Called 1s after ping start, to check if it timed out
- (void)endTime {
    if (self.simplePing) { // If it hasn't already been killed, then it's timed out
        [self failPing:@"timeout"];
    }
}

#pragma mark - Pinger delegate

// When the pinger starts, send the ping immediately
- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address {
     [self.simplePing sendPingWithData:nil];
}

- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error {
    [self failPing:@"didFailWithError"];
}

- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet error:(NSError *)error {
    // Eg they're not connected to any network
    [self failPing:@"didFailToSendPacket"];
}

- (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet {
    [self successPing];
}

@end

1 个答案:

答案 0 :(得分:0)

答案来自库中我修改为使用simplePing的一个代表。它造成了内存泄漏。我切换到找到here

的库 祝你好运,我希望这有助于其他人。