尝试从 Objective-C 到 Swift VC

Attempting to segue from Objective-C to Swift VC

我正在尝试从 objective-c 到 swift。

然而,当我使用下面的对象尝试此操作时,我收到以下错误

我不知道我做错了什么,我已经在故事板上设置了 segue 并将其分配给相同的 ID,创建了 prepare 函数和 perform。

- (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) 

在聊天中讨论并解决各种问题后,我会一一解决:

> *** 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];
});

修复此问题会发现第二个问题:

it segues but it trigger twice, do you know why this may happen?

您正在这样做:

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];
}

下一期,将数据传递到 Destination ViewController:

JSONViewController *destViewController = segue.destinationViewController;
destViewController.brand = @"something";

您正在混合使用 Swift 和 Objective-C,因为 XCode 抱怨不知道 brandJSONViewController 对象的 属性 ,您需要在 var 声明之前添加 @objc。可以找到更详细的答案

最后,使用 sender 传递 for 循环数据的技巧(在编码方面比创建另一个 var 等更快):

//Calling the performSegue with custom value to pass
[self performSegueWithIdentifier:@"brandSegue" sender:someVarToSend];

//Passing the custom value
destViewController.brand = someVarToSend;

我想更安全的方法是使用 navigationController?.pushViewController(_:animated:),而不是使用 segues。