尝试从 Objective-C 转向 Swift VC
Posted
技术标签:
【中文标题】尝试从 Objective-C 转向 Swift VC【英文标题】:Attempting to segue from Objective-C to Swift VC 【发布时间】:2017-11-09 17:03:06 【问题描述】:我正在尝试从 Objective-c 转换为 swift。
但是,当我使用下面的对象尝试此操作时,我收到以下错误
我不知道我做错了什么,我已经在情节提要上设置了 segue 并将其分配给相同的 ID,创建了准备函数和执行。
- (void)renderer:(id<SCNSceneRenderer>)renderer willRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time
// Look for trackables, and draw on each found one.
size_t trackableCount = trackableIds.size();
for (size_t i = 0; i < trackableCount; i++)
// NSLog(@"this is the variable value: %d", trackableIds[i]);
// Find the trackable for the given trackable ID.
ARTrackable *trackable = arController->findTrackable(trackableIds[i]);
// SCNCamera *camera = self.cameraNode.camera;
SCNNode *trackableNode = self.trackableNodes[i];
if (trackable->visible)
if (trackableIds[i] == 0)
NSLog(@"Starbucks");
[self performSegueWithIdentifier:@"brandSegue" sender:self];
else if (trackableIds[i] == 1)
NSLog(@"Dortios");
else
trackableNode.opacity = 0;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([segue.identifier isEqualToString:@"brandSegue"])
JSONViewController *destViewController = segue.destinationViewController;
编辑 - 错误消息
2017-11-09 16:57:05.232992+0000 MyARApp[2573:1099927] *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
2017-11-09 16:57:05.233169+0000 MyARApp[2573:1099927] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'
*** First throw call stack:
(0x186f51d04 0x1861a0528 0x186f51bd8 0x1878e1c24 0x1905e9c4c 0x19064646c 0x190432338 0x19038fe5c 0x1903fb6a8 0x190470bf0 0x1906ffb00 0x190701434 0x190703cd8 0x19070420c 0x190703c28 0x190467ab4 0x190707ae4 0x190b38854 0x190ca6b30 0x190ca69d4 0x1906f7e18 0x1020a27cc 0x19a66c610 0x19a725a84 0x19a723e00 0x19a724d1c 0x19a5a0cc4 0x19a6717ac 0x19a671b14 0x19a671f8c 0x19a71a67c 0x19a5d24a0 0x19a6e1c90 0x1035b949c 0x1035b945c 0x1035c8110 0x1035bc9a4 0x1035c9104 0x1035d0100 0x186b7afd0 0x186b7ac20)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
【问题讨论】:
控制台中是否有任何错误信息? 控制台中显示的完整错误是什么? @Larme 我更新了我的问题。dispatch_async(dispatch_get_main_queue(), ^()[self performSegueWithIdentifier:@"brandSegue" sender:self];);
改为?
您正在执行 for 循环:for (size_t i = 0; i < trackableCount; i++)
。您可能想添加一个break;
来结束它,不是吗?或者您是否需要检查所有这些值(因为在if (trackableIds[i] == 1)
中您还需要做其他事情?)如果您需要检查所有,只需在循环前添加一个BOOL needTobrandSegue = FALSE;
,将其设置为TRUE 以防==0
, 并在循环之后根据需要执行 segue。
【参考方案1】:
在Chat中讨论并修复各种问题后,我将一一解决:
> *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
> *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'
这是导致崩溃的第一个问题。这里说的是CocoaTouch的一个内部方法,需要在主线程中调用。
问题在于您的performSegueWithIdentifier:sender:
。所有与 UI 相关的调用都必须在主线程中完成。
修复它:
dispatch_async(dispatch_get_main_queue(), ^()
[self performSegueWithIdentifier:@"brandSegue" sender:self];
);
解决这个问题揭示了第二个问题:
它连续但触发了两次,你知道为什么会发生这种情况吗?
你正在这样做:
for (size_t i = 0; i < trackableCount; i++)
if (somethingTest)
[self performSegueWithIdentifier:@"brandSegue" sender:self];
谁说在你的 for 循环中你不能多次有效somethingTest
?
修复它(我说的是逻辑,我没有做dispatch_async(dispatch_get_main_queue()()
部分以避免给算法添加噪音)。
//Declare a var before the for loop
BOOL seguedNeedsToBeDone = FALSE;
for (size_t i = 0; i < trackableCount; i++)
if (somethingTest)
seguedNeedsToBeDone = TRUE;
//Perform the segue after the for loop if needed
if (seguedNeedsToBeDone)
[self performSegueWithIdentifier:@"brandSegue" sender:self];
下一期,将数据传递给目标视图控制器:
JSONViewController *destViewController = segue.destinationViewController;
destViewController.brand = @"something";
您正在混合使用 Swift 和 Objective-C,因为 XCode 抱怨不知道 brand
是 JSONViewController
对象的属性,因此您需要在声明 var 之前添加 @objc
。更详细的答案可以在here找到。
最后,传递你for循环数据的技巧是使用发送者(在编码方面比创建另一个var等更快):
//Calling the performSegue with custom value to pass
[self performSegueWithIdentifier:@"brandSegue" sender:someVarToSend];
//Passing the custom value
destViewController.brand = someVarToSend;
【讨论】:
【参考方案2】:我想更安全的方法是使用navigationController?.pushViewController(_:animated:),而不是使用segues。
【讨论】:
以上是关于尝试从 Objective-C 转向 Swift VC的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Swift 扩展访问 Objective-C 类的私有成员?
如何将此方法从 Objective-C 转换为 Swift?
再次将 textKit 从 Objective-C 转换为 Swift