Uitableview 调用self.tableView.reloadData需要10-15秒

Uitableview 调用self.tableView.reloadData需要10-15秒,uitableview,swift,reloaddata,eventkit,ekeventkit,Uitableview,Swift,Reloaddata,Eventkit,Ekeventkit,我正在尝试使用Swift将数据加载到表视图中。我的问题是显示数据需要10-15秒。数据最终会显示出来,但只需要花费很长时间。我正在从iCal检索事件,然后在表视图中显示它们。代码有问题吗 class EventsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet weak var eventCounterLabel: UILabel! @IBOutlet

我正在尝试使用Swift将数据加载到表视图中。我的问题是显示数据需要10-15秒。数据最终会显示出来,但只需要花费很长时间。我正在从iCal检索事件,然后在表视图中显示它们。代码有问题吗

class EventsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var eventCounterLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!

    var eventStore = EKEventStore()
    var calendar: EKCalendar?
    var events = NSMutableArray() as NSMutableArray
    var times = NSMutableArray() as NSMutableArray

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        //Table View Data Source and Delegate
        self.tableView.delegate = self
        self.tableView.dataSource = self

        //Event Kit access
        eventStore.requestAccessToEntityType(EKEntityTypeEvent,
            completion: {(granted: Bool, error:NSError!) in
                if !granted {
                    println("Access to store not granted")
                }else{
                    self.getTheCalendar()
                }
        })
    }

    //Event Kit Methods
    func getTheCalendar(){
        //Set the start and finish dates for events
        let start = NSDate() as NSDate
        let finish = NSDate() as NSDate

        //Make the predicate
        let eventPredicate =     self.eventStore.predicateForEventsWithStartDate(start, endDate: finish, calendars: nil) as NSPredicate

       self.eventStore.enumerateEventsMatchingPredicate(eventPredicate, usingBlock: { (event: EKEvent!, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
            if event != nil{
                self.events.addObject(event.title)
                self.times.addObject(event.startDate)
            }

            //Set the event counter label
            if self.events.count == 1{
                self.eventCounterLabel.text = "You have " + "\(self.events.count)" + " event today."
            }else{
                self.eventCounterLabel.text = "You have " + "\(self.events.count)" + " events today."
            }

            //Reload the table view
            self.tableView.reloadData()
        })
    }

    //Table View Methods
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.events.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath  indexPath: NSIndexPath) -> UITableViewCell {
        var cell:EventsTableViewCell =   self.tableView.dequeueReusableCellWithIdentifier("Cell") as   EventsTableViewCell

        //Set the event label
        cell.eventLabel.text = (self.events.objectAtIndex(indexPath.row) as String)

        cell.eventLabel.adjustsFontSizeToFitWidth = true

        //Set the event time label
        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute, fromDate:self.times.objectAtIndex(indexPath.row) as NSDate)

        let hour = components.hour as Int

        var theHourOfTheEvent = hour
        if theHourOfTheEvent < 12{

            if theHourOfTheEvent == 0{

                cell.eventTimeLabel.text = "All Day"

            }else{

                cell.eventTimeLabel.text = "\(theHourOfTheEvent)" + " am"

            }

        }else if theHourOfTheEvent > 12 && theHourOfTheEvent < 24{

            theHourOfTheEvent -= 12

            cell.eventTimeLabel.text = "\(theHourOfTheEvent)" + " pm"

        }else if theHourOfTheEvent == 24{

            theHourOfTheEvent -= 12

            cell.eventTimeLabel.text = "\(theHourOfTheEvent)" + " am"

        }else if theHourOfTheEvent > 24{

            theHourOfTheEvent -= 24

            cell.eventTimeLabel.text = "\(theHourOfTheEvent)" + " am"

        }else if theHourOfTheEvent == 12{

            cell.eventTimeLabel.text = "\(theHourOfTheEvent)" + " pm"

        }

        return cell
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 100.0
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    }
}
类事件视图控制器:UIViewController、UITableViewDelegate、UITableViewDataSource{
@IBOutlet弱var事件计数器标签:UILabel!
@IBVAR表格视图:UITableView!
var eventStore=EKEventStore()
var日历:EKCalendar?
var events=NSMutableArray()作为NSMutableArray
var times=NSMutableArray()作为NSMutableArray
覆盖功能视图将出现(动画:Bool){
超级。视图将显示(动画)
//表视图数据源和委托
self.tableView.delegate=self
self.tableView.dataSource=self
//事件工具包访问
eventStore.requestAccessToEntityType(eEntityTypeEvent,
完成:{(已授予:Bool,错误:NSError!)在中
如果!当然{
println(“未授予对存储的访问权”)
}否则{
self.getTheCalendar()
}
})
}
//事件工具包方法
func getTheCalendar(){
//设置事件的开始和完成日期
让start=NSDate()作为NSDate
让finish=NSDate()作为NSDate
//做谓语
将eventPredicate=self.eventStore.predicateForEventsWithStartDate(开始、结束日期:finish,日历:nil)设为NSPredicate
self.eventStore.enumerateEventsMatchingPredicate(eventPredicate,usingBlock:{(event:EKEvent!,stop:UnsafemeutablePointer)->中的Void
如果事件!=nil{
self.events.addObject(event.title)
self.times.addObject(event.startDate)
}
//设置事件计数器标签
如果self.events.count==1{
self.eventCounterLabel.text=“您今天有“+”\(self.events.count)“+”事件。”
}否则{
self.eventCounterLabel.text=“您今天有“+”\(self.events.count)“+”个事件。”
}
//重新加载表视图
self.tableView.reloadData()
})
}
//表视图方法
func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回self.events.count
}
func tableView(tableView:UITableView,cellForRowAtIndexPath:nsindepath)->UITableView单元格{
变量单元格:EventsTableViewCell=self.tableView.dequeueReusableCellWithIdentifier(“单元格”)作为EventsTableViewCell
//设置事件标签
cell.eventLabel.text=(self.events.objectAtIndex(indexath.row)作为字符串)
cell.eventLabel.adjustsFontSizeToFitWidth=true
//设置事件时间标签
让calendar=NSCalendar.currentCalendar()
让components=calendar.components(.CalendarUnitHour |.CalendarUnitMinute,fromDate:self.times.objectAtIndex(indexPath.row)作为NSDate)
设hour=components.hour为Int
var theHourOfTheEvent=小时
如果小时数小于12{
如果houroftheevent==0{
cell.eventTimeLabel.text=“全天”
}否则{
cell.eventTimeLabel.text=“\(theHourOfTheEvent)”+“am”
}
}否则,如果houroftheevent>12&&houroftheevent<24{
风的小时数-=12
cell.eventTimeLabel.text=“\(theHourOfTheEvent)”+“pm”
}否则,如果houroftheevent==24{
风的小时数-=12
cell.eventTimeLabel.text=“\(theHourOfTheEvent)”+“am”
}否则,如果事件时间>24{
风的小时数-=24
cell.eventTimeLabel.text=“\(theHourOfTheEvent)”+“am”
}否则,如果houroftheevent==12{
cell.eventTimeLabel.text=“\(theHourOfTheEvent)”+“pm”
}
返回单元
}
func tableView(tableView:UITableView,heightForRowAtIndexPath:nsindepath)->CGFloat{
返回100.0
}
func tableView(tableView:UITableView,didSelectRowAtIndexPath:nsindepath){
}
}

您正在EventKit枚举器内重新加载表视图

   self.eventStore.enumerateEventsMatchingPredicate(eventPredicate, usingBlock: { 
        ...
        self.tableView.reloadData()
    })
这意味着您要为日历中的每个检索到的事件重新加载一次,这可能是大量不必要的重新加载,而且速度很慢

在收集所有事件之后,您应该只调用此函数一次。将其移出循环,您应该会看到改进

   self.eventStore.enumerateEventsMatchingPredicate(eventPredicate, usingBlock: { 
        ...
    })
    self.tableView.reloadData()

您可能还希望在主线程上的调度块中调用它;更改UI的调用应该始终在主线程上,并且从您的示例中不清楚哪个线程正在执行代码


或者,您可能希望在获得元素后立即将其添加到表中—在这种情况下,不要使用
reloadTable
,而是在获取新数据时使用
insertRowsAtIndexPaths
。这比每次调用reloadData要便宜,因为它不会访问每个单元格,实际上只会访问屏幕上的单元格,如果在列表的末尾(而不是开始)添加新事件,这是便宜的