2015-02-20 2 views
0

У меня есть большой tableView, и я хочу добавить datePickers в tableView после того, как пользователь выберет ячейку.objc_getAssociatedObject() всегда nil

Я использую objc_setAssociatedObject() и objc_getAssociatedObject() вместо использования большого количества переменных.

Моя проблема: objc_getAssociatedObject() всегда NIL в cellForRowAtIndexPath ...

Это пример из моего кода: (предположим, что пользователь выбрал ячейку с рядом = 0)

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    ... 

    if indexPath.row == 1 { 
     var keypath = "datePicker\(indexPath.section)\(indexPath.row)" 
     println(objc_getAssociatedObject(self, &keypath)) 
     ... 
    } 

} 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let ip = NSIndexPath(forRow: indexPath.row+1, inSection: indexPath.section) 
    var keypath = "datePicker\(indexPath.section)\(indexPath.row+1)" 

    objc_setAssociatedObject(self, &keypath, UIDatePicker.alloc(), objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) 
    insertRowsAtIndexPaths([ip], withRowAnimation: .Top) 
} 
+0

Почему вы хотите создать более одного 'UIDatePicker'? И почему вашему контроллеру табличного представления нужны прямые ссылки на все эти сборщики дат? Почему бы просто не использовать собственный класс ячеек, который в случае необходимости помещает сборщик дат в свою иерархию подзаголовков и выставляет этот выбор даты как свойство в ячейке? Кроме того, [вы не должны называть 'alloc' в Swift. Вы должны просто сказать 'UIDatePicker()' для создания инициализированного выбора даты.] (Https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html) –

ответ

4

У вас есть две локальные переменные keyPath, поэтому, естественно, их адреса (&keypath) не совпадают. И именно этот адрес используется в качестве ключа.

Содействовать keyPath быть глобальным файловым уровнем. Теперь ваш код должен работать.

+0

Я не могу поставить 'keypath' как глобальный, потому что он не является постоянным. код является частью моего реального кода, который является большим. Я изменил его, чтобы быть более ясным. извините за неудобства. – Mohammed

+1

Он также может быть статическим членом 'struct' (или' class' в Swift 1.2). –

+1

@NateCook вы могли бы дать мне образец кода для тестирования? – Mohammed

0

Я не думаю, что есть причина, чтобы использовать objc_set/getAssociatedObject здесь-а Dictionary<String, UIDatePicker> должен делать то, что вам нужно, и, несомненно, будет гораздо менее подвержен ошибкам:

var datePickers: [String: UIDatePicker] = [:] 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    ... 

    if indexPath.row == 1 { 
     var keypath = "datePicker\(indexPath.row)" 
     println(datePickers[keypath]) 
     ... 
    } 

} 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let ip = NSIndexPath(forRow: indexPath.row+1, inSection: indexPath.section) 
    var keypath = "datePicker\(indexPath.row+1)" 

    datePickers[keyPath] = UIDatePicker() 
    insertRowsAtIndexPaths([ip], withRowAnimation: .Top) 
} 
+0

Название «keypath» зависит от раздела и строки. Это похоже на мой код: var keypath = "datePicker \ (indexPath.section) \ (indexPath.row)"; Этот метод упрощает мой код, потому что он быстро проверяет, есть ли datePicker в текущем indexPath, в функциях делегата таблицы, таких как cellForRowAtIndexPath и heightForRow и т. Д. – Mohammed

+0

Конечно, это сработает. Я просто использовал код из вашего вопроса, но никаких изменений в хранилище нет. –

0

Я не знаю, почему это не работает, поэтому я меняю свой код, чтобы добавить свойства NSIndexPath (s) для своего tableView и использовать их для отслеживания доступных datePickers.

это решит мою проблему, конечно.

0

Ваша проблема в том, что ключ ассоциации не остается последовательным.

Вот пример, в котором подробно описывается, как построить ключ ассоциации, который аккуратно завернут и будет оставаться последовательным. работа на iOS & OSX. (статическая строка постоянные работы по прошивке но не OSX)

class MyClass : NSObject 
{ 
    static let AssociationKey = UnsafePointer<Int>(bitPattern: 0) 

    var attactedProperty: String? 
    { 
     get 
     { 
      return objc_getAssociatedObject(self, MyClass.AssociationKey) as? String 
     } 
     set 
     { 
      objc_setAssociatedObject(self, MyClass.AssociationKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
     } 
    } 
} 

Так как объединение использует сырое значение указателя; Если вы используете static let AssociationKey = "fred", то неявная упаковка String в UnsafePointer<> создаст новый экземпляр обертки, когда он будет передан в objc_getAssociatedObject. Этот новый экземпляр имел бы другое значение указателя.

Смежные вопросы