Open9

iOS アプリ、クラッシュ、プロファイラ

nukopynukopy

Objective-C ブリッジの必要性について by o1

Swift には「純粋に Swift だけで JSON を扱う」ための組み込みの仕組みはなく(標準ライブラリには JSON パーサーがない)、Foundation フレームワークが提供する JSONSerialization クラスを使っているため、内部的に Objective-C の API を呼び出す必要が生じます。
その結果、Swift の配列や辞書 (Array / Dictionary) は、自動的に NSArray / NSDictionary にブリッジされてから JSONSerialization に渡されます。以下に詳しく説明します。


1. なぜ Objective-C ブリッジが必要なのか

  1. JSONSerialization は Foundation(Objective-C)に由来するクラス

    • もともと Apple の JSON シリアライゼーションは Objective-C 環境向けに NSJSONSerialization として提供されていました。
    • Swift から JSONSerialization を呼ぶときは、Objective-C の API をブリッジして利用している 形になります。
  2. Swift の配列/辞書 → Objective-C の配列/辞書

    • Swift では Array(値型)や Dictionary を使いますが、Objective-C 側では NSArray / NSDictionary(参照型)が期待されます。
    • そこで、Swift ランタイムが 自動的にブリッジング を行い、Swift コレクションを一時的に NSArray / NSDictionary として見せかけます。
    • この過程で Copy-on-Write (COW) の仕組みや、メモリ共有の問題が絡んでくるため、同時アクセスが起きるとエラーが顕在化しやすくなります。
  3. Swift だけで完結した JSON 機能がない

    • Swift 標準ライブラリには、たとえば JSONSerialization 相当の機能が組み込まれていません。
    • Swift の近代的なアプローチとしては Codable (Encodable/Decodable) がありますが、これも裏側では Foundation と連携しているため、最終的には同様にブリッジが走る箇所があります。

2. 「Swift まま」で動かない理由

  • Foundation への依存

    • iOS / macOS の標準的な API 群(UIKit、AppKit、Foundation など)は、もともと Objective-C で実装されており、Swift はそれをブリッジして利用する立場です。
    • そのため、純粋に Swift のデータ構造を Objective-C API に渡す場合、自動ブリッジング を挟まざるを得ません。
  • 言語仕様の違い

    • Swift の ArrayDictionary は値型 (struct) ですが、Objective-C の NSArray / NSDictionary は参照型 (class) です。
    • 「同じように見えるコレクション」でもメモリモデルや所有権の扱いが異なるため、ブリッジングで変換やラップを行う必要があります。
  • COW とブリッジングの複雑化

    • Swift 側では効率化のため Copy-on-Write を使っているのに対し、Objective-C 側では別のメモリ管理が行われます。
    • このギャップを埋めるのが「ブリッジ」であり、ここで 同時アクセス (data race) のリスクも高まります。

3. まとめ

  • Objective-C ブリッジが必要な理由:
    Swift アプリが JSON を扱う際、実際には JSONSerialization (Foundation) という Objective-C を起源としたクラスを呼び出しているので、自動的に配列や辞書を NSArray / NSDictionary にブリッジする仕組みが必要になります。

  • 「Swift まま」では動かないのか?

    • 現状の Apple のエコシステムでは、完全に Swift ネイティブで完結した JSON パーサー は標準では提供されておらず、最終的に Foundation (Objective-C) の機能に依存します。
    • たとえば Codable を使う方法もありますが、それも内部実装は大半が Foundation に依存するため、ブリッジングの問題から完全には逃れられません。

結局、「Swift まま」動くかどうか は、アプリが どのフレームワークの機能を使って JSON を処理しているか にかかっており、Apple 公式の JSON 処理は Objective-C 由来の API であるため、ブリッジが必須となっているのです。

nukopynukopy

NS ってなに? by o1

NS は、元々 NeXTSTEP(ネクストステップ)という OS/開発環境に由来する接頭辞です。

NeXTSTEP とは

  • NeXT, Inc.(スティーブ・ジョブズが 1985 年に Apple を追われた後に立ち上げた企業)が開発した UNIX ベースの OS/GUI 環境です。
  • その後、Apple が NeXT を買収し、NeXTSTEP をベースに macOS(当時の名称は OpenStep → Mac OS X)を構築しました。

NS が残っている理由

  • Objective-C のフレームワーク として長らく使われてきた FoundationAppKit などのクラス名は、NeXTSTEP 時代のコードを継承しているため、当時の名残で NS という接頭辞が付いています。
  • たとえば、NSString, NSArray, NSDictionary, NSDate などのクラスは、NeXTSTEP 由来のクラスとして誕生し、現在も NS の頭文字が残っているわけです。

現在の扱い

  • Swift が登場した今でも、Apple の主要フレームワークは「Cocoa (Objective-C)」ベース であり、NS で始まるクラスが広く利用されています。
  • Swift 専用にラップされた構造(String, Array, Dictionary など)は同じ機能を持ちながらも、内部的には多くの場合、Foundation の NS クラスとブリッジ しているため、依然として NS という名前が随所で目に入ります。

要するに、NSNeXTSTEP に由来し、歴史的な理由で現在も Apple のフレームワークにおいて Objective-C のクラスや関数名 の先頭に付いている接頭辞です。