Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 为什么只有在选择x86“U 64模拟器”时才会出现Complie错误;无法引用块内具有数组类型的声明";_Ios_Objective C_Iphone_Xcode_Block - Fatal编程技术网

Ios 为什么只有在选择x86“U 64模拟器”时才会出现Complie错误;无法引用块内具有数组类型的声明";

Ios 为什么只有在选择x86“U 64模拟器”时才会出现Complie错误;无法引用块内具有数组类型的声明";,ios,objective-c,iphone,xcode,block,Ios,Objective C,Iphone,Xcode,Block,我的问题是:为啥仅在使用 x86_64编译时会出现此编译错误?以及如何解决? 我的问题是:为什么只有当select x86_64模拟器编译错误发生时才发生?如何解决 环境: Xcode v8.3.2 测试代码: + (BOOL)updateSqlByFileName:(NSString *)file key:(NSString *)key, ... { va_list args; va_start(args, key); __block BOOL isOK = NO;

我的问题是:为啥仅在使用 x86_64编译时会出现此编译错误?以及如何解决?
我的问题是:为什么只有当select x86_64模拟器编译错误发生时才发生?如何解决

环境: Xcode v8.3.2
测试代码:

+ (BOOL)updateSqlByFileName:(NSString *)file key:(NSString *)key, ...
{
    va_list args;
    va_start(args, key);

    __block BOOL isOK = NO;
    [_queue inDatabase:^(FMDatabase *_dataBase)//
    {
        isOK = [_dataBase executeUpdate:sql withVAList:args];
    }];

    va_end(args);
    return isOK;
}
不同的编译方式,编译错误情况
  • 【编译正常√】选择 通用iOS设备编译(建造)时:【armv7+arm64】

    CompileC Test.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    CompileC Test.m normal arm64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    
  • 【编译正常√】 选择真机: iPhone4(7.1.2)编译(建造)时:【armv7】

    CompileC Test.m normal armv7 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    
  • 【编译错误×】选择模拟器: iphone5s(10.3)、iphonese(10.3)、iphone7plus(10.3)编译(建造)时:【x86_64】

    CompileC Test.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    
    复杂错误
    无法引用块内具有数组类型的声明

  • 【编译正常√】选择模拟器: iphone5(10.3)编译(建造)时:【i386】

    CompileC Test.m normal i386 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    

经过尝试【有效的】解决方案(代码): 参考代码(灵感来源): FMDB类库里的 行刑函数

- (FMResultSet *)executeQuery:(NSString*)sql, ... {
    va_list args;
    va_start(args, sql);

    id result = [self executeQuery:sql withArgumentsInArray:nil orDictionary:nil orVAList:args];

    va_end(args);
    return result;
}
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args {
    //xxx
}

经过尝试【有效的】解决方案(代码): 参考代码(灵感来源): FMDB类库里的 行刑函数

- (FMResultSet *)executeQuery:(NSString*)sql, ... {
    va_list args;
    va_start(args, sql);

    id result = [self executeQuery:sql withArgumentsInArray:nil orDictionary:nil orVAList:args];

    va_end(args);
    return result;
}
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args {
    //xxx
}

如果一个块捕获了一个非\u块变量,则在块中创建并存储该块时,会生成该变量的副本。数组不能用C赋值,这可能就是块的设计者不允许在块中捕获数组类型的变量的原因

什么类型的
va_list
不是由C标准指定的;它是特定于实现的。它可以实现为数组类型、指针类型、结构类型或其他类型,在同一编译器上的不同体系结构中,这可能是不同的。他们可能在x86_64中实现为数组类型,也可能实现为一些非数组类型在其他3种体系结构上。这没有什么不寻常的。你不能假设什么类型的
va_list

在您的回答中,您定义了另一个函数并将
va_list
传递给它,在
va_list
是一个数组类型的情况下,这恰好起作用,因为C会自动将“T的数组”类型的任何参数调整为“指向T的指针”,因此方法
+foo:key:withVAList:
中的参数
args
实际上有一个指针类型,而
va_list
是数组类型(与
+foo:key:
方法中的
args
不同),指针变量可以捕获到块中

另一种解决方案是获取
va_列表
的地址,获取
va_列表*
,并将其放入块中使用的变量中。无论
va_列表
是什么,这都保证是指针类型,并且可以在块中很好地捕获。当您需要在中使用实际的
va_列表
时在块的一侧,可以取消对指针的引用。例如,类似以下内容:

+ (BOOL)updateSqlByFileName:(NSString *)file key:(NSString *)key, ...
{
    va_list args;
    va_start(args, key);
    va_list *ptrToArgs = &args;

    __block BOOL isOK = NO;
    [_queue inDatabase:^(FMDatabase *_dataBase)
    {
        isOK = [_dataBase executeUpdate:sql withVAList:*ptrToArgs];
    }];

    va_end(args);
    return isOK;
}

如果一个块捕获了一个非\u块变量,则在块中创建并存储该块时,会生成该变量的副本。数组不能用C赋值,这可能就是块的设计者不允许在块中捕获数组类型的变量的原因

什么类型的
va_list
不是由C标准指定的;它是特定于实现的。它可以实现为数组类型、指针类型、结构类型或其他类型,在同一编译器上的不同体系结构中,这可能是不同的。他们可能在x86_64中实现为数组类型,也可能实现为一些非数组类型在其他3种体系结构上。这没有什么不寻常的。你不能假设什么类型的
va_list

在您的回答中,您定义了另一个函数并将
va_list
传递给它,在
va_list
是一个数组类型的情况下,这恰好起作用,因为C会自动将“T的数组”类型的任何参数调整为“指向T的指针”,因此方法
+foo:key:withVAList:
中的参数
args
实际上有一个指针类型,而
va_list
是数组类型(与
+foo:key:
方法中的
args
不同),指针变量可以捕获到块中

另一种解决方案是获取
va_列表
的地址,获取
va_列表*
,并将其放入块中使用的变量中。无论
va_列表
是什么,这都保证是指针类型,并且可以在块中很好地捕获。当您需要在中使用实际的
va_列表
时在块的一侧,可以取消对指针的引用。例如,类似以下内容:

+ (BOOL)updateSqlByFileName:(NSString *)file key:(NSString *)key, ...
{
    va_list args;
    va_start(args, key);
    va_list *ptrToArgs = &args;

    __block BOOL isOK = NO;
    [_queue inDatabase:^(FMDatabase *_dataBase)
    {
        isOK = [_dataBase executeUpdate:sql withVAList:*ptrToArgs];
    }];

    va_end(args);
    return isOK;
}