异步调用在多线程代码部分中不起作用(MKOverlay canDraw)

发布于 2024-11-18 11:15:29 字数 2145 浏览 3 评论 0原文

我可以通过 NSURLConnection 从代码库中的任何其他部分成功异步检索数据,但子类 TileOverlayView 类中的 canDrawMapRect 函数除外。

我正在修改名为tileMap 的MapKit 示例,以从服务器下载图块并将该信息覆盖在地图上。在 canDrawMapRect 中,我调用了覆盖类中的一个函数,该函数又创建了 url 并打开了一个连接。我已经测试了我的连接类并确认它确实有效。我已经在overlay和overlayView的init函数中成功运行了它。网址也很好,因为我可以将它们放入浏览器中,它们会显示正确的 png。我知道 canDrawMapRect 在多个线程上运行,而且我对线程只有新手经验。

这是我的连接代码,

- (id)initWithStringUrl: (NSString*) url {

    NSLog(@"Test Connect Init URL %@", url);

    self = [super init];
    if (self)
    {
        [self loadURL:[NSURL URLWithString:url]];    
    }

    return self;
}
+ (UIImage*)connectSynchronousWithURL:(NSString*) url {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

    NSURLResponse* response = [[NSURLResponse alloc] init];
    NSError* error = [[NSError alloc] init];
    NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    UIImage *image = [UIImage imageWithData: data];

    return image;
}
- (BOOL)loadURL:(NSURL *)inURL {
    NSURLRequest *request = [NSURLRequest requestWithURL:inURL];
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];

    if (conn) {
        receivedData = [[NSMutableData data] retain];
        NSLog(@"Connection Success");
    } else {
        NSLog(@"Connection Failed");        
        return FALSE;
    }

    return TRUE;
}
- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"didReceiveResponse");
    [receivedData setLength:0]; 
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data {
    NSLog(@"didReceiveData");
    [receivedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn {
    NSLog(@"Succeeded! Received %d bytes of data", [receivedData length]);
}

非常标准的东西。如果我在 TileOverlayView 的 init 中运行代码,它会工作得很好,但如果我在 canDrawMapRect 中运行它,则不会调用任何委托函数。我想还值得一提的是,与服务器的同步连接确实可以在 canDrawMapRect 方法中工作。我根本不明白 T_T

任何帮助将不胜感激。谢谢。

I can successfully retrieve data asynchronously through NSURLConnection from any other part in the code base except in the canDrawMapRect function in my subclassed TileOverlayView class.

I'm modifying the MapKit sample called tileMap to download tiles from a server and overlay that information on the map. In the canDrawMapRect I call a function in the overlay class which in turn creates the url and opens up a connection. I have already tested my connection class and have confirmed that it does indeed work. I've run it in the init functions of overlay and overlayView with success. The urls are good too since I can throw them in a browser and they show the right pngs. I know that canDrawMapRect is running on multiple threads and I only have novice experience with threads.

Here is my connection code,

- (id)initWithStringUrl: (NSString*) url {

    NSLog(@"Test Connect Init URL %@", url);

    self = [super init];
    if (self)
    {
        [self loadURL:[NSURL URLWithString:url]];    
    }

    return self;
}
+ (UIImage*)connectSynchronousWithURL:(NSString*) url {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

    NSURLResponse* response = [[NSURLResponse alloc] init];
    NSError* error = [[NSError alloc] init];
    NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    UIImage *image = [UIImage imageWithData: data];

    return image;
}
- (BOOL)loadURL:(NSURL *)inURL {
    NSURLRequest *request = [NSURLRequest requestWithURL:inURL];
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];

    if (conn) {
        receivedData = [[NSMutableData data] retain];
        NSLog(@"Connection Success");
    } else {
        NSLog(@"Connection Failed");        
        return FALSE;
    }

    return TRUE;
}
- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"didReceiveResponse");
    [receivedData setLength:0]; 
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data {
    NSLog(@"didReceiveData");
    [receivedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn {
    NSLog(@"Succeeded! Received %d bytes of data", [receivedData length]);
}

Pretty standards stuff. If I run the code in the init of TileOverlayView it'll work just fine but if I run it in canDrawMapRect then none of the delegate functions get called. I suppose it's also worth mentioning that the synchronous connection to the server does work in the canDrawMapRect method. I don't get it at all T_T

Any help would be greatly appreciated. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

从﹋此江山别 2024-11-25 11:15:29

从有关 NSURLConnection 的文档来看,这几乎概括了这一点。

请注意,这些委托方法将在为关联的 NSURLConnection 对象启动异步加载操作的线程上调用。

看起来我需要使用 CFRunLoopRun() 和 CFRunLoopStop(CFRunLoopGetCurrent()); 来保持线程处于活动状态。或者找到在线程中进行这些异步调用的替代方法。

From the docs about NSURLConnection, this pretty much sums it up.

Note that these delegate methods will be called on the thread that started the asynchronous load operation for the associated NSURLConnection object.

Looks like I'll be needing to use CFRunLoopRun() and CFRunLoopStop(CFRunLoopGetCurrent()); to keep the thread alive. Or find an alternative to making these async calls in the thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文