Xcode 抛出 'atomic_notify_one<unsigned long>' 不可用

Xcode throws 'atomic_notify_one<unsigned long>' is unavailable

我在 Mac 上安装了 Xcode 12,尝试构建在 android 上完美运行的 React 本机应用程序,并获得 'atomic_notify_one<unsigned long>' is unavailable。这是我从错误中得到的最多信息。

这个错误是 flipper 的错误。 Flipper 抛出了几个描述性较低的错误,我不得不在我的播客文件中对其进行评论。评论后,这个错误停止了。

  1. 修复 Podfile 如下图所示
  2. cd ios
  3. 删除 Pods 文件夹和 Podfile.lock
  4. pod 安装
  5. 连播更新
  6. cd .. && npx react-native 运行-ios

您需要在 Podfile 中的 Flipper 代码下方进行评论:

use_flipper!
post_install do |installer|
    flipper_post_install(installer)
  end

今天 iOS 模拟器更新到 iOS 14.5 后,此问题再次发生。 “Shared S Katre”发布的答案似乎是一个很好的解决方法。

因为React-Native是开源代码,我想iOS任何大的更新都一定能带来突破性的改变。我想这些会在以后修复。

无论如何 - 问题似乎出在 Flipper 上,它用作 RN 的调试工具 (https://reactnative.dev/blog/2020/03/26/version-0.62)。

如果您只需要构建项目,只需在 pod 文件中注释掉 flipper,然后像这样重新安装 pods。

播客文件

# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable the next line.
# use_flipper!()

接下来,重新安装您的 pods。我 cd 到项目的根目录并使用了 npx。

$ npx pod-install

最后,尝试构建和 运行 您的项目:

$ npx react-native run-ios

更新:

根据评论,看起来这个问题现在已经修复了。如果你想要鳍状肢,你应该能够恢复你的 Podfile 并更新鳍状肢。

参见:

感谢堆垛机!

我必须在 AppDelegate.m 中注释所有 #ifdef FB_SONARKIT_ENABLED,将 hermes 设置为 false 并在 Podfile 中注释 Flipper。

最后删除Pods和Podfile.lock,然后pod install

我在 XCode 12.5 中构建时遇到了同样的问题。如果暂时禁用 Flipper 不适合您,您可以降级到 XCode 12.4。这为我修好了。您可以在此处下载 XCode 12.4:https://developer.apple.com/download/more

如果有人仍然有这个错误(我刚刚更新了 Mac、Xcode 等),您可以在不禁用 Flipper 和 Hermes 的情况下修复构建;在 post_install 下的 Pod 文件中只需添加(我在网上某处找到它并更改它以修复最新更新的新错误):

post_install do |installer|
    flipper_post_install(installer)
    react_native_post_install(installer)

    # # to build for the simulator on Apple M1
    # installer.pods_project.targets.each do |target|
    #   target.build_configurations.each do |config|
    #     # disables arm64 builds for the simulator
    #     config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
    #   end
    # end

    ## Fix for XCode 12.5 & RN 0.62.2 - See https://github.com/facebook/react-native/issues/28405
    find_and_replace("../node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm",
      "_initializeModules:(NSArray<id<RCTBridgeModule>> *)modules", "_initializeModules:(NSArray<Class> *)modules")

    find_and_replace("../node_modules/react-native/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm",
      "RCTBridgeModuleNameForClass(strongModule))", "RCTBridgeModuleNameForClass(Class(strongModule)))")

    ## Fix for Flipper-Folly on iOS 14.5
    find_and_replace("Pods/Flipper-Folly/folly/synchronization/DistributedMutex-inl.h",
      "atomic_notify_one(state)", "folly::atomic_notify_one(state)")

    find_and_replace("Pods/Headers/Private/RCT-Folly/folly/synchronization/DistributedMutex-inl.h",
      "atomic_notify_one(state)", "folly::atomic_notify_one(state)")

    find_and_replace("Pods/Flipper-Folly/folly/synchronization/DistributedMutex-inl.h",
      "atomic_wait_until(&state, previous | data, deadline)", "folly::atomic_wait_until(&state, previous | data, deadline)")
  end

在您的 target 之前添加

# fixes for last Mac updates
def find_and_replace(dir, findstr, replacestr)
  Dir[dir].each do |name|
      text = File.read(name)
      replace = text.gsub(findstr,replacestr)
      if text != replace
          puts "Fix: " + name
          File.open(name, "w") { |file| file.puts replace }
          STDOUT.flush
      end
  end
  Dir[dir + '*/'].each(&method(:find_and_replace))
end

这里没有注释掉 flipper,而是一个对我有用的解决方案。

将 Podfile 中的 flipper 更新为如下所示

use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })

运行 pod repo update 在 ios 文件夹内

最后,使用

更新您的项目pods

pod install

我认为@opensw 提供的答案会起作用,但我发现了一些更强大的解决方案,因此它每次都可以与 pod install 一起使用,而无需删除 Pods 文件夹。 首先,更改 add/Replace Podfile

中的这一行
use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })

现在在上面几行中提到的最新版本中修复了 Flipper-folly 的问题 但是我们还需要注意 RCT 的愚蠢行为,为此,我们将使用 find_and_replace 函数。 这是我从 here

获得的新功能
# Define find-and-replace function
  def find_and_replace(dir, findstr, replacestr)
    Dir[dir].each do |name|
        text = File.read(name)
        replace = text.gsub(findstr,replacestr)
        replaced = text.index(replacestr)
        if replaced == nil && text != replace
            puts "Fix: " + name
            File.open(name, "w") { |file| file.puts replace }
            STDOUT.flush
        end
    end
    Dir[dir + '*/'].each(&method(:find_and_replace))
  end

现在从 post-install 调用这个函数,所以我们需要在 post_install do |installer|

中添加以下 2 个函数调用
 find_and_replace("Pods/RCT-Folly/folly/synchronization/DistributedMutex-inl.h",
                   "atomic_notify_one(state)", "folly::atomic_notify_one(state)")

  find_and_replace("Pods/RCT-Folly/folly/synchronization/DistributedMutex-inl.h",
  "atomic_wait_until(&state, previous | data, deadline)", "folly::atomic_wait_until(&state, previous | data, deadline)")

这是我在 Github

中的回答

稍微扩展一下 Umang 和 opensw 的答案。

我已将 find_and_replace 更新如下。请注意,我添加了 system("chmod +w " + name) 来修复 Permission denied @ rb_sysopen 错误。

def find_and_replace(dir, findstr, replacestr)
  Dir[dir].each do |name|
      text = File.read(name)
      replace = text.gsub(findstr,replacestr)

      if text != replace
          puts "Fix: " + name
          system("chmod +w " + name)
          File.open(name, "w") { |file| file.puts replace }
          STDOUT.flush
      end
  end
  Dir[dir + '*/'].each(&method(:find_and_replace))
end

这是我的脚蹼配置

use_flipper!({ 'Flipper' => '0.87.0', 'Flipper-Folly' => '2.5.3', 'Flipper-RSocket' => '1.3.1' })

至于修复文件,就我而言,截至 4 月 30 日的最新版本仅在一个地方更新 DistributedMutex-inl.h 就足够了。

另外,请注意我是如何在函数名称前添加两个额外的空白符号的。这是必需的,因此 pod install 不会在后续调用中破坏代码。

  post_install do |installer|
    flipper_post_install(installer)
    react_native_post_install(installer)

    find_and_replace("Pods/RCT-Folly/folly/synchronization/DistributedMutex-inl.h",
          "  atomic_notify_one(state);", "  folly::atomic_notify_one(state);")
  end

刚刚评论了这一行并解决了这个问题-

  # use_flipper!
  # post_install do |installer|
  #   flipper_post_install(installer)
  # end

根据您的 React Native 版本,将 Podfile 中所有当前的 flipper 代码替换为以下代码:

add_flipper_pods!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })

use_flipper!({ 'Flipper-Folly' => '2.5.3', 'Flipper' => '0.87.0', 'Flipper-RSocket' => '1.3.1' })

然后使用此更新 Pods 项目:

cd ios && pod install && cd ..

我在将项目从 RN 0.63 升级到 0.64(并使用 Xcode 12.5)时遇到了同样的问题,但投票最高的答案并没有为我解决问题,我很想避免任何额外的脚本。

我注意到 Upgrade Helper 播客文件中的一些变化 - 特别是从 flipper_post_install(installer)react_native_post_install(installer) 的变化。我进行了此更改并快速访问了我的 pods 目录,然后 运行 pod install --repo-update 并为我修复了它 :)

我还注意到安装 pods 后 DistributedMutex 文件(有问题的文件)的补丁是 运行,所以在我看来这应该是正确的修复

奖励:这也让我能够删除旧的 flipper_post_install 脚本,我在之前的升级

中位于我的 podfile 顶部

将atomic_nofiy_one替换为folly::atomic_notify_one,完整的podfile如下:

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

def add_flipper_pods!
  version = '~> 0.33.1'
  pod 'FlipperKit', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitLayoutPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/SKIOSNetworkPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitUserDefaultsPlugin', version, :configuration => 'Debug'
  pod 'FlipperKit/FlipperKitReactPlugin', version, :configuration => 'Debug'
end

# Post Install processing for Flipper
def flipper_post_install(installer)
  installer.pods_project.targets.each do |target|
    if target.name == 'YogaKit'
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '4.1'
      end
    end
  end
end

target 'AwesomeProject' do
  # Pods for AwesomeProject
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  target 'AwesomeProjectTests' do
    inherit! :complete
    # Pods for testing
  end

  use_native_modules!

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable these next few lines.
  add_flipper_pods!
  post_install do |installer|
    flipper_post_install(installer)
    ## Fix for XCode 12.5 beta
    find_and_replace("../node_modules/react-native/React/CxxBridge/RCTCxxBridge.mm",
        "_initializeModules:(NSArray<id<RCTBridgeModule>> *)modules", "_initializeModules:(NSArray<Class> *)modules")
    find_and_replace("../node_modules/react-native/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm",
    "RCTBridgeModuleNameForClass(strongModule))", "RCTBridgeModuleNameForClass(Class(strongModule)))")
    find_and_replace("Pods/Flipper-Folly/folly/synchronization/DistributedMutex-inl.h",
             "  atomic_notify_one(state);", "  folly::atomic_notify_one(state);")
  end
end

target 'AwesomeProject-tvOS' do
  # Pods for AwesomeProject-tvOS

  target 'AwesomeProject-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

def find_and_replace(dir, findstr, replacestr)
  Dir[dir].each do |name|
        text = File.read(name)
        replace = text.gsub(findstr,replacestr)

        if text != replace
            puts "Fix: " + name
            File.open(name, "w") { |file| file.puts replace }
            STDOUT.flush
        end
    end
    Dir[dir + '*/'].each(&method(:find_and_replace))
end