2016-11-19 1 views
0

こんにちは、私はParseLiveQueryは..私はアレイ内の項目を割り当てることはできません...

私の問題があるを使用してデータを取得しようとしている_ArrayProtocol内の項目を割り当てることができません

import Foundation 
import Parse 
import ParseLiveQuery 

extension _ArrayProtocol where Iterator.Element == PFObject { 
    mutating func updateWithEvent(event: Event<PFObject>) { 
     switch event { 
     case .created(let object): 
       append(object) 
     case .entered(let object): 
       append(object) 
     case .deleted(let object): 
      if let index = index(of: object) { 
       remove(at: index) 
      } 
     case .left(let object): 
      if let index = index(of: object) { 
       remove(at: index) 
      } 
     case .updated(let object): 
      if let index = index(of: object) { 
       //I got an error : Cannot assign through subscript: subscript is get-only 
       self[index] = object 

      } 
     } 
    } 
} 

ここに問題があります

case .updated(let object): 
       if let index = index(of: object) { 
        //I got an error : Cannot assign through subscript: subscript is get-only 
        self[index] = object 

       } 
      } 

誰でも知っていますか?

答えて

1

まず、内部の種類とプロトコルの操作には注意が必要です。プロトコル名(_ArrayProtocol)の前に付いているアンダースコアはちょうどこれを示しています。 Swiftを使用している開発者が内部プロトコルの直接的/明示的な使用に頼ってはならないため、将来のSwift更新で警告なしに変更を促す可能性があることを意味します。 swift/stdlib/public/core/ArrayType.swiftから

internal protocol _ArrayProtocol: RangeReplaceableCollection, ... 


、あなたのエラーについては、エラーメッセージがかなり

を言っていることはsubscriptて割り当てることができません:subscript_ArrayProtocolために得る専用

、すなわち、subscriptには利用できていませんあなたの拡張機能の型自体として_ArrayProtocolを使用しているので、デフォルトの実装を介して)それはsubscriptの青写真に対する設定を持っていますが、デフォルトの実装はありませんが、ゲッターのデフォルトの実装はRangeReplaceableCollectionから利用できます。

Elementself)をindexに置き換えたい場合は、たとえば次のようにします。分のため、我々は内部プロトコルで直接作業の不適切の主題を残す場合は、我々が構築できる

replaceSubrange(index...index, with: [object]) 

RangeReplaceableCollectionに自身が準拠プロトコルとして、_ArrayProtocolに準拠するタイプに変異replaceSubRange(_:, with:) method of RangeReplaceableCollectionアクセスを利用しますこのフィックスを実装する例です。実際に検証できる例です(あなたの質問であなたが提供したものとは対照的に...)。

enum Foo { 
    case created(Int) 
    case entered(Int) 
    case deleted(Int) 
    case left(Int) 
    case updated(Int) 
} 

// do not work directly with this _internal_ protocol!! 
extension _ArrayProtocol where Iterator.Element == Int { 
    mutating func updateWithEvent(event: Foo) { 
     switch event { 
     case .created(let object): 
      append(object) 
     case .entered(let object): 
      append(object) 
     case .deleted(let object): 
      if let index = index(of: object) { 
       remove(at: index) 
      } 
     case .left(let object): 
      if let index = index(of: object) { 
       remove(at: index) 
      } 
     case .updated(let object): 
      if let index = index(of: object) { 
       replaceSubrange(index...index, with: [object]) 
      } 
     } 
    } 
} 

ただし、このような拡張機能を内部プロトコルに実装しないでください。代わりに、公開タイプ/プロトコルへの拡張を実装することを検討してください。

enum Foo<T> { 
    case created(T) 
    case entered(T) 
    case deleted(T) 
    case left(T) 
    case updated(T) 
} 

extension Array where Element: Equatable { 
    mutating func updateWithEvent(event: Foo<Element>) { 
     switch event { 
     case .created(let object): 
      append(object) 
     case .entered(let object): 
      append(object) 
     case .deleted(let object): 
      if let index = index(of: object) { 
       remove(at: index) 
      } 
     case .left(let object): 
      if let index = index(of: object) { 
       remove(at: index) 
      } 
     case .updated(let object): 
      if let index = index(of: object) { 
       self[index] = object 
      } 
     } 
    } 
} 

注意ここに(あなた自身の延長、selfの使用量など)の内部_ArrayProtocolの具体的な種類での作業とは対照的に、その、持っている:Equatableに準拠Element年代に拘束Arrayの拡張機能として、 subscriptArray、もう1つはdoesのセッターがありません。これは、拡張子がArrayに適用されたときに、オリジナルの単純な要素置換self[index] = objectを適用できることを意味します。

+0

ありがとうございました。完璧に動作しています! –

+0

@スンウォクベクは喜んで援助します。 – dfri

+0

_ArrayProtocolはSiwft 3.1では公開されなくなりましたが、同じタイプの要件を使用することができます(これは単純化しています):http://stackoverflow.com/questions/43338557/does-arraytype-or-arrayprotocol-not-available-イン・スウィフト3-1。 –

関連する問題