简体   繁体   中英

Assigning UITableView delegate and dataSource to super in Swift

I am trying to have a super class fill and handle the contents of a table for a certain segment. So I thought of implementing:

@IBAction func changeValue(sender:AnyObject){
    self.searchDisplayController?.setActive(false, animated:false)
    if (selection.selectedSegmentIndex==1){
        self.myTableView.delegate=super
        self.myTableView.dataSource=super

    } else {
        self.myTableView.delegate=self
        self.myTableView.dataSource=self
    }
    self.myTableView.reloadData()
}

Yet I have an error. By way of testing, the compiler suggested me to use:

    @IBAction func changeValue(sender:AnyObject){
    self.searchDisplayController?.setActive(false, animated:false)
    if (selection.selectedSegmentIndex==1){
        self.myTableView.delegate=super.self()
        self.myTableView.dataSource=super.self()

    } else {
        self.myTableView.delegate=self
        self.myTableView.dataSource=self
    }
    self.myTableView.reloadData()
}

whatever the meaning of construct super.self()

Yet, notwithstanding the code passes through there without any problem, the command seems to be ignored and the delegate methods are called on the same class instead of the super one and even printing the value of super.self() shows it is the current class, notwitstanding, when I skip the (), Xcode encourges me by saying:

Function produces expected type 'LogsViewController'; did you mean to call it with '()'?

Yet when I add the double parenthesis it returns the current class instead of the top LogsViewController. What is the correct way of implementing what I need, and why super.self() does not work as it is advertised?

I clarify I cannot simply call the delegate methods on super as that shall retain the ownership to the bottom class and virtual methods on a top class shall find the methods in the bottom class instead of the one of the super one as it would be needed.

That its the structure of my code, hoping it makes things clearer: Bottom Class

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    let isMainTable = tableView==self.myTableView
    let isFavorite = selection.selectedSegmentIndex==2
    var count: Int?
    count = sourceForTableKind(isMainTable, favorites:isFavorite)?.count
    if (count==nil) {
        return 0
    }
    return count!
}

Top "virtual class":

func sourceArray()->Array<NearElement>?{
    return nil
}

func arrayOfContentsFromSearchArray(searchArray:Array<String>?, favorites:Bool)->Array<NearElement>?{
    return nil
}

func sourceForTableKind(normal: Bool, favorites:Bool)->Array<NearElement>?{
    // NSLog(@"source:%@ %@",favorites?@"favorites": @"near", normal?@"normal":@"searched");
    print("sono \(self)")
    if (normal) {
        return sourceArray()
    } else {
        return arrayOfContentsFromSearchArray(searchResults, favorites:favorites)
    }
}

The implementations of sourceArray() and arrayOfContentsFromSearchArray() are defined both in the bottom class and its super class both inheriting from this class.

Simply because when you are assigning delegate you are assigning instances. So if the delegate method is called it will call the object's method which is an instance of "self" class.

When you assign it to super it keeps referencing to your instance and it doesn't matter if you used "self" or "super"(this is to confirm).

What you should do, in your class implementation of the delegate method call the super's implementation.

you have to put:

myTableView.delegate = self
myTableView.dataSource = self

When you assign it to super it keeps referencing to your object and it doesn't matter if you used "self" or "super".

A solution for this case would be:

  • Superclass implements tableview's delegate and datasource methods.
  • A separate class (called for example TableDelegate ) which implements tableview's delegate and datasource methods.

      if (selection.selectedSegmentIndex == 1) { self.myTableView.delegate = self; self.myTableView.dataSource = self; } else { self.myTableView.delegate = instanceOfTableDelegate; self.myTableView.dataSource = instanceOfTableDelegate; }` 

When superclass delegate, datasource are needed to be called, assign self, Swift will find the implementation from the superclass, otherwise assign to the class which is used only as delegate and datasource for the tableview.

I ended up, as also suggested, by calling the super on all delegate methods. Of course it would have been cleaner to switch the table or its delegate and dataSource to the top class, but that simply does not work in Swift.

Yet, even this pushes the virtual function to call the bottom implementation. Calling the top delegate methods does not apparently change the active instance the virtual function finds when implementing its methods. Of course I would need to awkwardly send upwards even the implementations, but this is definitely a bug of the support.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM