我有一个UIButton设置在视图在故事板和链接到一个动作。该操作运行一些代码,通过NSURLSessionDataTask调用PHP页面(该页面反过来在MySql数据库中记录记录)。
当我触摸按钮一次,看到日志打印出来在日志屏幕内的XCode我可以看到我打印的消息一次,但如果我检查MySql DQ我可以看到多个相同的记录插入。
我一开始认为可能是PHP代码,但如果我通过web浏览器直接加载PHP页面,我不会得到这个问题,只有当通过ios代码运行时。
是否有办法阻止一个按钮代码被执行超过?
来自UIButtons action的代码:
- (void)UpdateActions{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://xxx/mobilescript/setactions.php"]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
NSString *postString = [[NSString alloc] initWithFormat:@"imgname=%@",imageName];
NSString *clearPost = [postString stringByReplacingOccurrencesOfString:@"var=" withString:@""];
[request setHTTPBody:[clearPost dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:clearPost forHTTPHeaderField:@"Content-Length"];
[NSURLConnection connectionWithRequest:request delegate:self];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString * returnStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",returnStr);
}];
[task resume];
}
代码来自PHP:
<?php
include_once("DB_SETTING.php"); //Includes DB settings
$DB_HANDLE = mysql_connect( "$DB_SERVER" , "$DB_USERNAME" , "$DB_PASSWORD" ) or $errors[] = mysql_error();
if(!mysql_select_db( "$DB_NAME" ))
{
$errors[] = "Unable to select database $DB_NAME";
}
if($errors){
echo '<pre>';
foreach($errors as $result) {
echo $result . ' <br>';
}
echo '</pre>';
}
//Check all settings are in place
if(!isset($_REQUEST["imgname"]) )
{
echo("-1");
}
else
{
$sql = "INSERT INTO `WS_ACTIONS` ( `ID` , `imgid` ,`memberid` )
SELECT 0,tb3.id,tb2.id FROM WS_MEMBERS tb2,WS_IMAGES tb3 WHERE `IMGNAME` = '".$_REQUEST["imgname"]."' and tb2.email = '".$_REQUEST["email"]."' And NOT EXISTS (
SELECT
tb1.ID
FROM
WS_ACTIONS tb1
inner join
WS_IMAGES tb2
on
tb2.id = tb1.imgid
inner join
WS_MEMBERS tb3
on
tb3.id = tb1.memberid
where
imgname = '".$_REQUEST["imgname"]."'
and
tb3.email = '".$_REQUEST["email"]."'
)";
mysql_query($sql);
echo($sql);
}
?>
如果你有一个按钮的实例,你可以启用/禁用它。另一种解决方案是创建BOOL来保存按钮是否应该执行某些操作
例子:
- (void)UpdateActions{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://xxx/mobilescript/setactions.php"]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
NSString *postString = [[NSString alloc] initWithFormat:@"imgname=%@",imageName];
NSString *clearPost = [postString stringByReplacingOccurrencesOfString:@"var=" withString:@""];
[request setHTTPBody:[clearPost dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:clearPost forHTTPHeaderField:@"Content-Length"];
[NSURLConnection connectionWithRequest:request delegate:self];
NSURLSession *session = [NSURLSession sharedSession];
// disable your button if you have a reference to it
[self.yourBtn setEnabled:NO]; // or set your BOOL to NO here
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// regardless of the response once your request had finished just enable your button again
[self.yourBtn setEnabled:YES]; // or set your BOOL to YES here
NSString * returnStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",returnStr);
}];
[task resume];
}
编辑您可以像这样尝试使用NSURLConnection
:
- (void)UpdateActions{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://xxx/mobilescript/setactions.php"]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
NSString *postString = [[NSString alloc] initWithFormat:@"imgname=%@",imageName];
NSString *clearPost = [postString stringByReplacingOccurrencesOfString:@"var=" withString:@""];
[request setHTTPBody:[clearPost dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:clearPost forHTTPHeaderField:@"Content-Length"];
[NSURLConnection connectionWithRequest:request delegate:self];
// disable your button if you have a reference to it
[self.yourBtn setEnabled:NO]; // or set your BOOL to NO here
// create NSOperation to run your request on background
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
// run your request on this peration queue
[NSURLConnection sendAsynchronousRequest:request
queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSString * returnStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",returnStr);
// do whatever you want with the response
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Main thread work (UI usually)
[self.yourBtn setEnabled:YES];
}];
}];
}
问题是您向服务器启动了两个请求。当您用这一行创建请求时,
[NSURLConnection connectionWithRequest:request delegate:self];
立即从服务器开始下载。然后,通过用这行创建一个NSURLSessionDataTask(然后调用[task resume]),从服务器开始另一个下载,
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
如果你正在使用NSURLSession,你不应该也调用connectionWithRequest:delegate:,所以删除那一行应该可以解决你的问题。