2016-10-12 4 views
0

現在私の最初の素早いプロジェクトに取り組んでおり、次のコードで混乱しています。私は理解できることを示すために行ごとに注釈を付けます。Swiftはこのコードが何をしているのか混乱しています

したがって、IAPヘルパークラスの値に基づいてトリガーするための通知が使用されています。

NotificationCenter.default.addObserver(self, selector: #selector(MasterViewController.handlePurchaseNotification(_:)), 
name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification),object: nil 

これは上記のnsnotificationに記載されている方法です。今私の最初の質問は、これはns通知を受け取ったときに自動的に呼び出されますか? 2番目の行では、変更できない変数としてプロダクトIDを定義し、ガードを特定のタイプに設定します。つまり、この場合は文字列でなければなりません。 私が混乱している2行はforループだと思っていましたが、反復処理がそれほどわかりません。最後の行がチェックを満たしたときの動作であると仮定してIm

func handlePurchaseNotification(_ notification: Notification) { 
guard let productID = notification.object as? String else { return } 

for (index, product) in products.enumerated() { 
    guard product.productIdentifier == productID else { continue } 

    tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .fade) 
} 

ご協力いただきありがとうございました!

答えて

1

これは、ns通知を受け取ったときに自動的に呼び出されますか?

はい、それは私がコードにコメントしましたaddObserver(_:selector:name:object:)

の全体のポイントです:

func handlePurchaseNotification(_ notification: Notification) { 
// convert notification.object to string if you can, and call it productID. Otherwise return 
guard let productID = notification.object as? String else { return } 

// products.enumerated() would yield something like 
// [(0, productA), (1, productB), (2, productC)] 
// This array is iterated, with the index and product being set to the values from each tuple in turn 

for (index, product) in products.enumerated() { 
// check if the current product's productIdentifier is == to productID, otherwise keep searching 
    guard product.productIdentifier == productID else { continue } 

// if we get to here, it's implied the productIdentifier == productID 

// reload the row with the corresponding index 
    tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .fade) 
} 

最後の行は少し愚かであることを。 reloadRows(at:with:)は、Array<IndexPath>を引数として取ります。このコードでは、すべての反復で新しい配列が作成され、その反復から生成された単一の要素のみが含まれます。すべてのIndexPathインスタンスを含む配列を作成し、最後にreloadRows(at:with:)を1回呼び出す方が効率的です。

ここで私は一緒に従うことがはるかに簡単だと思うこれは、この方法が私の感想です:

func handlePurchaseNotification(_ notification: Notification) { 
    guard let desiredID = notification.object as? String else { return } 

    let staleRows = products.enumerated() // convert an array of products into an array tuples of indices and products 
     .filter{ _, product in product.ID == desiredID } // filter to keep only products with the desired ID 
     .map{ index, _ in IndexPath(row: index, section: 0) } // create an array of IndexPath instances from the indexes 

    tableView.reloadRows(at: staleRows, with: .fade) 
} 
関連する問題