我正在为iOS编写一个简单的Adobe原生扩展。
它所做的一切都显示了一个UISwitch。
然而,当我试图在UISwitch上设置frame(或这段代码中的任何UIView),甚至访问UISwitch的框架时,应用程序会出现错误的内存访问崩溃。UISwitch本身不是零,因为在它上面调用setOn是有效的,如果我不尝试在它上面呼叫setFrame,或者设置它的中心,或者以任何方式定位它,UISwitch确实会出现在屏幕上。
这是代码。有问题的函数是第一个:showSwitch()
#import "FlashRuntimeExtensions.h"
#import <UIKit/UIKit.h>
FREObject showSwitch(FREContext context,
void* functionData,
uint32_t argc,
FREObject argv[])
{
int32_t isOn;
FREGetObjectAsInt32(argv[0], &isOn);
id delegate = [[UIApplication sharedApplication] delegate];
UIWindow* window = [delegate window];
// The following will segfault
// UISwitch* switchControl = [[[UISwitch alloc] initWithFrame:CGRectMake(100, 100, 0, 0)];
// This works fine.
UISwitch* switchControl = [[[UISwitch alloc] init] retain];
// This will segfault as well
// [switchControl setFrame:CGRectMake(100, 100, switchControl.frame.size.width, switchControl.frame.size.height)];
[switchControl setOn:(isOn == 1)]; // switchControl is not nil, because this works.
[window addSubview:switchControl];
return NULL;
}
void ContextFinalizer(FREContext context)
{
return;
}
void ContextInitializer(void* extensionData,
const uint8_t* contextType,
FREContext context,
uint32_t* numFunctionsToTest,
const FRENamedFunction** functionsToSet)
{
*numFunctionsToTest = 1;
FRENamedFunction* function = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*1);
function[0].name = (const uint8_t*)"showSwitch";
function[0].functionData = NULL;
function[0].function = &showSwitch;
*functionsToSet = function;
}
void ExtensionInitializer(void** extensionDataToSet,
FREContextInitializer* contextInitializerToSet,
FREContextFinalizer* contextFinalizerToSet)
{
*extensionDataToSet = NULL;
*contextInitializerToSet = &ContextInitializer;
*contextFinalizerToSet = &ContextFinalizer;
}
void ExtensionFinalizer(void* extensionData)
{
return;
}
我在向窗口添加视图时遇到了同样的问题,经过大量搜索和测试,我找到了这个解决方案,这可能会帮助任何有同样问题的人。
以这种方式添加子视图:
[[[[UIApplication sharedApplication] keyWindow] rootViewController].view addSubview: switchControl];
获取AppDelegate(不要忘记包含.h文件)。然后将开关添加到窗口或rootViewController中。
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[app.window addSubview:switchControl];