色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

您好,歡迎來電子發燒友網! ,新用戶?[免費注冊]

您的位置:電子發燒友網>源碼下載>數值算法/人工智能>

使用Swift擴展的“錯誤”方式

大小:0.5 MB 人氣: 2017-10-11 需要積分:1
?
  翻譯如下:非常感謝,這篇文章很不錯。我一直疑惑你為什么要用這么多不必要的擴展,我認為你并未按照正確的用途來使用它們。能否簡單地將它們當作一個整體類?
  我使用擴展的主要原因是為了增加可讀性。在這些地方我喜歡使用擴展,盡管“這并不是擴展設計的初衷”。
  私有Helper函數
  在OC語言中,.h和.m文件維護起來一樣煩人,從.h文件中可以很容易地看出類的外部API,而內部API則保存在.m文件中。但在Swift中,我們只有一個文件。
  因此,我們很容易看出類的公共函數:可以從外部及私有部分所訪問的函數。我將私有內部函數放在私有擴展中,如下例:
  // it‘s easy to glance and see which parts of this struct are// supposed to be used externallystructTodoItemViewModel { letitem: TodoItem letindexPath: NSIndexPath vardelegate: ImageWithTextCellDelegate { returnTodoItemDelegate(item: item) } varattributedText: NSAttributedString { // the itemContent logic is in the private extension// keeping this code clean and easy to glance atreturnitemContent } } // keeps all this internal logic out of the public-facing API of this struct// MARK: Private Attributed Text Builder Helper Methodsprivateextension TodoItemViewModel { staticvarspaceBetweenInlineImages: NSAttributedString { returnNSAttributedString(string: “ ”) } varitemContent: NSAttributedString { lettext = NSMutableAttributedString(string: item.content, attributes: [NSFontAttributeName : SmoresFont.regularFontOfSize(17.0)]) ifletdueDate = item.dueDate { appendDueDate(dueDate, toText: text) } forassignee initem.assignees { appendAvatar(ofUser: assignee, toText: text) } returntext } func appendDueDate(dueDate: NSDate, toText text: NSMutableAttributedString) { ifletcalendarView = CalendarIconView.viewFromNib() { calendarView.configure(withDate: dueDate) ifletcalendarImage = UIImage.imageFromView(calendarView) { appendImage(calendarImage, toText: text) } } } func appendAvatar(ofUser user: User, toText text: NSMutableAttributedString) { ifletavatarImage = user.avatar { appendImage(avatarImage, toText: text) } else{ appendDefaultAvatar(ofUser: user, toText: text) downloadAvatarImage(forResource: user.avatarResource) } } func downloadAvatarImage(forResource resource: Resource?) { ifletresource = resource { KingfisherManager.sharedManager.retrieveImageWithResource(resource, optionsInfo: nil, progressBlock: nil) { image, error, cacheType, imageURL iniflet_ = image { dispatch_async(dispatch_get_main_queue()) { NSNotificationCenter.defaultCenter().postNotificationName(TodoItemViewModel.viewModelViewUpdatedNotification, object: self.indexPath) } } } } } func appendDefaultAvatar(ofUser user: User, toText text: NSMutableAttributedString) { ifletdefaultAvatar = user.defaultAvatar { appendImage(defaultAvatar, toText: text) } } func appendImage(image: UIImage, toText text: NSMutableAttributedString) { text.appendAttributedString(TodoItemViewModel.spaceBetweenInlineImages) letattachment = NSTextAttachment() attachment.image = image letyOffsetForImage = -7.0asCGFloat attachment.bounds = CGRectMake(0.0, yOffsetForImage, image.size.width, image.size.height) letimageString = NSAttributedString(attachment: attachment) text.appendAttributedString(imageString) } }
  注意:在上例中,屬性字符串計算的邏輯超級復雜。如果存在于結構(struct)的主要部分中,我們就無法輕易發現它,并了解哪個部分比較重要了(在OC語言中這個部分是屬于.h文件的)。 這樣做也會使得代碼更干凈。
  尤其如果這個屬性字符串在代碼中其他地方還有調用的話,使用這樣的長擴展將邏輯重構到自身結構中會是很好的開頭。不過在編寫代碼時,將它放在私有擴展中會更好。
  分組
  一開始我在Swift中真正使用擴展的原因在于:Swift剛出來的時候,無法添加pragma mark注釋。沒錯,Swift出現后我想用它做的第一件事就是這個。在OC代碼中,我通過pragma mark來進行區分,換到Swift后還想繼續用。
  于是我去了WWDC的Swift Labs,詢問如何在Swift中添加pragma marks,回答者建議我使用擴展來替代。于是我開始使用擴展了,并完全愛上了這種用法。
  盡管pragma marks(在Swift中是//MARK)非常棒,但在新寫的代碼中很容易忘記添加MARK,對于編碼風格多樣的團隊來說更是如此。結果就是該MARK的函數沒MARK上,不該加的反而有了。因此,如果一組函數之間相互歸屬,我傾向于將它們放在同一個擴展中。
  一般我總會有一個擴展是將所有ViewController或者AppDelegate的初始樣式設計方法歸類到一起的:
  private extension AppDelegate { func configureAppStyling() { styleNavigationBar() styleBarButtons() } func styleNavigationBar() { UINavigationBar.appearance().barTintColor= ColorPalette.ThemeColorUINavigationBar.appearance().tintColor= ColorPalette.TintColorUINavigationBar.appearance().titleTextAttributes= [ NSFontAttributeName : SmoresFont.boldFontOfSize(19.0), NSForegroundColorAttributeName : UIColor.blackColor() ] } func styleBarButtons() { let barButtonTextAttributes = [ NSFontAttributeName : SmoresFont.regularFontOfSize(17.0), NSForegroundColorAttributeName : ColorPalette.TintColor] UIBarButtonItem.appearance().setTitleTextAttributes(barButtonTextAttributes, forState: .Normal) } }
  或者將所有通知邏輯歸類到一起:
  extension TodoListViewController { // called in initfunc addNotificationObservers() { NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector(“onViewModelUpdate:”), name: TodoItemViewModel.viewModelViewUpdatedNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector(“onTodoItemUpdate:”), name: TodoItemDelegate.todoItemUpdatedNotification, object: nil) } func onViewModelUpdate(notification: NSNotification) { ifletindexPath = notification.objectas? NSIndexPath { tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) } } func onTodoItemUpdate(notification: NSNotification) { ifletitemObject = notification.objectas? ValueWrapper《TodoItem》 { letupdatedItem = itemObject.valueletupdatedTodoList = dataSource.listFromUpdatedItem(updatedItem) dataSource = TodoListDataSource(todoList: updatedTodoList) } } }
  協議一致性
  This is a special case of grouping. 我喜歡將所有符合同一個協議的函數放在同一個擴展中。在OC語言中我是用pragma mark來實現的,但我更偏愛擴展的硬分隔和可讀性:
  structTodoItemViewModel { staticletviewModelViewUpdatedNotification = “viewModelViewUpdatedNotification”letitem: TodoItem letindexPath: NSIndexPath vardelegate: ImageWithTextCellDelegate { returnTodoItemDelegate(item: item) } varattributedText: NSAttributedString { returnitemContent } } // ImageWithTextCellDataSource Protocol Conformance extension TodoItemViewModel: ImageWithTextCellDataSource { varimageName: String { returnitem.completed ? “checkboxChecked”: “checkbox”} varattributedText: NSAttributedString { returnitemContent } }
  用擴展對UITableViewDataSource與UITableViewDelegate進行分割也很奏效。
  // MARK: Table View Data Sourceextension TodoListViewController: UITableViewDataSource{ func numberOfSectionsInTableView(tableView: UITableView) -》 Int { returndataSource.sections.count} func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -》 Int { returndataSource.numberOfItemsInSection(section) } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -》 UITableViewCell{ let cell = tableView.dequeueReusableCellWithIdentifier(String.fromClass(ImageWithTextTableViewCell), forIndexPath: indexPath) as! ImageWithTextTableViewCell let viewModel = dataSource.viewModelForCell(atIndexPath: indexPath) cell.configure(withDataSource: viewModel, delegate: viewModel.delegate) returncell } } // MARK: Table View Delegateextension TodoListViewController: UITableViewDelegate{ // MARK: Cell Selectionfunc tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { performSegueWithIdentifier(todoItemSegueIdentifier, sender: self) } // MARK: Section Header Configurationfunc tableView(tableView: UITableView, viewForHeaderInSection section: Int) -》 UIView? { ifdataSource.sections[section] == TodoListDataSource.Section.DoneItems{ let view = UIView() view.backgroundColor= ColorPalette.SectionSeparatorColorreturnview } returnnil} func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -》 CGFloat{ ifdataSource.sections[section] == TodoListDataSource.Section.DoneItems{ return1.0} return0.0} // MARK: Deleting Actionfunc tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -》 Bool { returntrue} func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -》 [UITableViewRowAction]? { let deleteAction = UITableViewRowAction(style: .Destructive, title: “Delete”) { [weakself] action , indexPath in iflet updatedTodoList = self?.dataSource.listFromDeletedIndexPath(indexPath) { self?.dataSource= TodoListDataSource(todoList: updatedTodoList) } } return[deleteAction] } }
  模型
  我在OC中使用Core Data時非常喜歡使用模型,因為在更改時模型由Xcode生成,因此需要將函數或任何其他內容放入同一個擴展或分類中。
  我嘗試盡可能在Swift中使用結構,但還是更喜歡用擴展來分出模型屬性與基于屬性的計算。對我來說,這樣增加了模型代碼的可讀性。
  總結
  盡管這種做法也許不夠“傳統”,在Swift中對擴展的超簡單運用能極大程度地改善代碼,讓代碼超級具有可讀性。

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

      發表評論

      用戶評論
      評價:好評中評差評

      發表評論,獲取積分! 請遵守相關規定!

      ?
      主站蜘蛛池模板: 国产剧果冻传媒星空在线观看| 搞基福利社| 动漫女主被扒开双腿羞辱| 黄小说免费看| 午夜理伦片免费| 动漫美女无衣| 日本亚洲电影| 成人无码精品一区二区在线观看| 嫩草欧美曰韩国产大片| 真实国产熟睡乱子伦对白无套| 狠狠色狠狠色综合日日91app| 亚洲国产综合人成综合网站00| 国产色婷婷精品人妻蜜桃成熟| 爽娇妻快高h| 国产成人综合在线| 日日啪在线影院百度| 第一会所欧美无码原创| 三级貂蝉艳史 在线观看| 俄罗斯兽交XXXXX在线| 天美麻豆成人AV精品视频| 国产精品99久久久精品无码 | china chinese中国人玩| 免费看www视频| free乌克兰性xxxxhd| 秋霞伦理高清视频在线| 俄罗斯17vidio| 校花的奶好大好浪| 精品久久久久中文字幕日本| 一个人免费视频在线观看高清版| 久久xxxx| 99久久久无码国产精品AAA| 热久久综合这里只有精品电影| 福利社影院| 亚洲精品理论电影在线观看| 久久精品亚洲AV中文2区金莲| 5278欧美一区二区三区| 琪琪see色原网色原网站| 国产精品色无码AV在线观看| 亚洲精品嫩草研究院久久| 菊地凛子av| 成人无码在线视频区|