防止UIButtons动作运行不止一次


Prevent UIButtons action running more than once

我有一个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:,所以删除那一行应该可以解决你的问题。