块在异步线程上执行两次
Posted
技术标签:
【中文标题】块在异步线程上执行两次【英文标题】:Block gets executed twice on async thread 【发布时间】:2015-12-07 12:33:44 【问题描述】:我有一个奇怪的问题。我有一个类在后台线程上调用另一个类中的方法,但是它在线程 2 上两次获取数据,然后一旦完成,例如将其放入线程 4。有谁知道为什么?
调用方法的类:
-(void)awakeFromNib
NSString *swedbankRate;
CurrencyViewHelper *currencyRates = [[CurrencyViewHelper alloc]init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
swedbankRate = [currencyRates getSwedbankRates];
NSLog(@"%@", swedbankRate);
);
所以来自 CurrencyViewHelper 的部分是:
-(NSString *)getSwedbankRates
// Set to empty String in case there is some issue
swedbankRate = @"";
// Get Data from Swedbank
NSString *swedbankURL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://www.swedbank.ee/private/d2d/payments2/rates/currency?language=EST"]
encoding:NSASCIIStringEncoding
error:nil];
NSArray *swedbankArray = [swedbankURL componentsSeparatedByString:@"<tr>"];
NSString *swedbankString = swedbankArray[18];
swedbankArray = [swedbankString componentsSeparatedByString:@"<tr>"];
NSString *swedbankDirty = swedbankArray[0];
// Check if the fetched data corresponds to RUB data
if ([swedbankDirty containsString:@"RUB"])
swedbankDirty = [swedbankDirty stringByReplacingOccurrencesOfString:@"<td class=\"numeric-cell\">"
withString:@""];
swedbankDirty = [swedbankDirty stringByReplacingOccurrencesOfString:@"\n"
withString:@""];
swedbankDirty = [swedbankDirty stringByReplacingOccurrencesOfString:@" "
withString:@""];
NSArray *swedbankCleanArray = [swedbankDirty componentsSeparatedByString:@"</td>"];
swedbankDirty = swedbankCleanArray[4];
// Set result to value fetched from internet
swedbankRate = [NSString stringWithFormat:@"%.2f", [swedbankDirty floatValue]];
结果是
2015-12-07 14:26:29.635 Photography[60338:18355297] 71.14
2015-12-07 14:26:29.684 Photography[60338:18355293] 71.14
我无法理解它为什么会执行两次?
该方法应该做的是扫描网页的 html 代码并从整个内容中获取一个浮点数供我以后使用。是的,代码并不完美,还在学习中。欢迎任何想法。
【问题讨论】:
如果它运行了两次,那是因为awakeFromNib
被调用了两次。我会在该方法中添加一个日志以进行验证。然后我会将代码移到其他地方。
【参考方案1】:
awakeFromNib 通常不适合这种事情。您应该使用 awakeFromNib 来执行您本来想在 Interface Builder 中执行的操作,但由于某种原因不能 - 所以只是为了解决加载 nib 文件时出现的问题。
例如,如果您在不同的上下文中使用相同的类,并且如果您在代码中构建用户界面而不是使用 nib 文件,并且您的 awakeFromNib 不会在一切都了。
【讨论】:
我主要是尝试用一些数据填充标签,在我从网页获取这些数据之前,我无法做到这一点,这就是为什么我想把整个事情从 nib 中唤醒。但是视图确实加载并等待一个分裂的 secodn 值更新为新的值也不是那么糟糕。【参考方案2】:检查awakeFromNib
是否在您的应用中被调用了两次... (see this question)
【讨论】:
【参考方案3】:你说的都是对的。哇,这是多么愚蠢的错误。事实上,另一个班级也在调用 awakeFromNib 来做它的事情。
我将这些调用放在 viewDidLoad 方法中,它现在可以按需要工作了!伟大的!学习这种多线程东西的好方法! :)
【讨论】:
以上是关于块在异步线程上执行两次的主要内容,如果未能解决你的问题,请参考以下文章
如果异步调用不一定在不同的线程上执行,阻塞异步调用如何导致死锁?