構造体も構造体ポインタもどちらも渡せるが、構造体ポインタのときはmemoryとたくさん書くことになる。ソース可読性を優先すると構造体の方がよさそう。速度については構造体ポインタの方が若干速いようだ。
swift1.2
Optimization Level : Fasttest [-O]
1,000,000回の呼び出し
構造体版 6,898 us
構造体ポインタ版 5,371 us
main.m
#import <Foundation/Foundation.h> #import "caller.h" #import "sample-swift.h" int main(int argc, const char * argv[]) { @autoreleasepool { invoke(); } return 0; }
caller.h
#import <Foundation/Foundation.h> typedef struct Params_t { int32_t v; int32_t* p; int32_t** pp; } Params; @protocol Jedi - (void)useTheForceWithParams:(Params)params; - (void)useTheForceWithParamsPointer:(Params*)p_params; @end void invoke(void);
caller.m
#import "caller.h" #import "sample-swift.h" void invoke(void){ { Callee* callee = [[Callee alloc] init]; Params params; params.v = 1; int32_t a = 2; params.p = &a; int32_t x1 = 3; int32_t x2 = 4; int32_t* y[2] = {&x1, &x2}; params.pp = y; [callee useTheForceWithParams:params]; assert( params.v == 1 ); assert( a == 11 ); assert( x1 == 12 ); assert( x2 == 13 ); } { Callee* callee = [[Callee alloc] init]; Params params; params.v = 1; int32_t a = 2; params.p = &a; int32_t x1 = 3; int32_t x2 = 4; int32_t* y[2] = {&x1, &x2}; params.pp = y; [callee useTheForceWithParamsPointer:¶ms]; assert(params.v == 14); assert(a == 15); assert(x1 == 16); assert(x2 == 17); } }
callee.swift
import Foundation @objc class Callee : NSObject, Jedi { override init(){ super.init() } func useTheForceWithParams(params:Params){ assert(params.v == 1) assert(params.p[0] == 2) params.p[0] = 11 var qq:UnsafeMutablePointer<UnsafeMutablePointer<Int32>> = params.pp assert( qq[0][0] == 3 ) assert( qq[1][0] == 4 ) qq[0][0] = 12 qq[1][0] = 13 } func useTheForceWithParamsPointer(p_params:UnsafeMutablePointer<Params>){ assert(p_params.memory.v == 1) assert(p_params.memory.p[0] == 2) p_params.memory.v = 14 p_params.memory.p[0] = 15 var qq:UnsafeMutablePointer<UnsafeMutablePointer<Int32>> = p_params.memory.pp assert(qq[0][0] == 3) assert(qq[1][0] == 4) qq[0][0] = 16 qq[1][0] = 17 } }
sample-Bridging-Header.h
#import "caller.h"