为啥使用 tableView.dequeueReusableCellWithIdentifier 会出现运行时错误

     2023-02-23     212

关键词:

【中文标题】为啥使用 tableView.dequeueReusableCellWithIdentifier 会出现运行时错误【英文标题】:Why do I get a runtime error with using tableView.dequeueReusableCellWithIdentifier为什么使用 tableView.dequeueReusableCellWithIdentifier 会出现运行时错误 【发布时间】:2015-06-20 19:18:11 【问题描述】:

我正在学习 Swift 中的基本表格视图,并在尝试使用 tableView.dequeueResuableCellWithIdentifier 时遇到了问题。

每次调用此方法时,我都会创建一个新的 UITableViewCell(例如 var cell = UITableViewCell() ),但我知道这是非常低效的,不是最佳实践。现在,使用我在下面粘贴的代码,我在 'var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! 处收到运行时错误! UITableViewCell'。

我已经指定了一个 Prototype 单元,并给它一个重用标识符“单元”。

class ViewController: UIViewController, UITableViewDataSource 

let devCourses = [
    ("iOS App Dev with Swift Essential Training","Simon Allardice"),
    ("iOS 8 SDK New Features","Lee Brimelow"),
    ("Data Visualization with D3.js","Ray Villalobos"),
    ("Swift Essential Training","Simon Allardice"),
    ("Up and Running with AngularJS","Ray Villalobos"),
    ("MySQL Essential Training","Bill Weinman"),
    ("Building Adaptive Android Apps with Fragments","David Gassner"),
    ("Advanced Unity 3D Game Programming","Michael House"),
    ("Up and Running with Ubuntu Desktop Linux","Scott Simpson"),
    ("Up and Running with C","Dan Gookin") ]

func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return 1


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return devCourses.count


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell

    let (courseTitle, courseAuthor) = devCourses[indexPath.row]

    cell.textLabel?.text = courseTitle
    return cell

我得到的唯一输出是 (lldb),所以我不知道问题出在哪里。我正在使用 Xcode 6.3.2。

谢谢!

【问题讨论】:

你在哪里注册表格视图的单元格标识符? 从情节提要中,我在表格视图中选择了原型单元格,然后在属性检查器中的标识符字段中输入了“单元格”。 您说您在特定行中有运行时错误,但您唯一的输出是 lldb。你确定你没有在该行设置断点吗? 我很尴尬地承认这一点,但这就是我所做的 Emilio。我不是故意的,所以我一定是不小心做了。谢谢!! 【参考方案1】:

如果您使用的是标准单元,看起来就像是这样,您仍然需要将该类注册为要出列的单元类。现在,您是 tableView 不知道要出列什么类型。

viewDidLoad这个方法中,你应该做这样的事情:

self.tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")

这样,表格视图将正确地将该表格的标识符为"cell" 的单元格出列。

【讨论】:

【参考方案2】:

如果您想确保 Storyboards 中的其他内容不会覆盖注册,请尝试以下操作:

override func viewDidLoad() 
    super.viewDidLoad()

    // Make sure that "cell" is the name of the reuse identifier. Maybe use a const in M file to set it.
    let nibName = UINib(nibName: "YourNibName", bundle:nil)
    self.tableView.registerNib(nibName, forCellReuseIdentifier: "cell")

由于viewDidLoad 发生在笔尖加载之后,这将确保无论是什么导致了问题,你都会得到最后的决定——除非它在你的代码中的其他地方。

struct UIConstants 
    struct SomeViewControllerUIConstants 
        static let cellNibName          = "SpecialCell";
        static let cellReuseIdentifier  = "cell";
    

另外,也许考虑声明一个伪const struct 如上所述。这将减少导致这种运行时异常的拼写或大写问题的可能性,顺便说一下,我认为 Apple 不妨花几个小时进行编程以更优雅地处理。为什么不进行不区分大小写的搜索,或者不区分字符串距离大小写,以查看它是否可以在 01 的距离内找到一个匹配项?反正我跑题了。

【讨论】:

【参考方案3】:

我可以使您的代码无需更改即可工作。关键在于故事板的正确设置。

    确保您的 Storyboard 中的 ViewController 的类在 Identity Inspector 中设置为 ViewController。注意,不是UIViewController

    确保已设置 tableView 数据源。您可以 control 从 Storyboard 中的 tableView 拖动到顶部的 ViewController 图标,然后从弹出窗口中选择 dataSource

    确保原型单元格的重用标识符设置为“单元格”。

【讨论】:

【参考方案4】:

谢谢大家的回答。事实证明我做了一些愚蠢的事情——我不小心在那行添加了一个断点。 EmilioPelaez 认为这可能是问题所在,而且确实如此。代码现在按预期工作。

再次感谢!

【讨论】:

为啥不继承 UIApplication?为啥要使用委托?

】为啥不继承UIApplication?为啥要使用委托?【英文标题】:WhynotsubclassUIApplication?Whyuseadelegate?为什么不继承UIApplication?为什么要使用委托?【发布时间】:2012-05-2604:47:09【问题描述】:除了使用应用程序委托以便UIApplication单例... 查看详情

为啥或为啥不在 C++ 中使用 memset? [关闭]

】为啥或为啥不在C++中使用memset?[关闭]【英文标题】:WhyorwhynotusememsetinC++?[closed]为什么或为什么不在C++中使用memset?[关闭]【发布时间】:2014-10-0418:40:49【问题描述】:我必须维护一个程序中有很多memset。在现代C++中使用memset... 查看详情

为啥在参数周围使用 /*、*/ 以及为啥在提取数组长度时使用 >>>? [复制]

】为啥在参数周围使用/*、*/以及为啥在提取数组长度时使用>>>?[复制]【英文标题】:Whyuse/*,*/aroundargumentsandwhyuse>>>whenextractingthelengthofanarray?[duplicate]为什么在参数周围使用/*、*/以及为什么在提取数组长度时使用>... 查看详情

为啥我们使用 cellIdentifier?

】为啥我们使用cellIdentifier?【英文标题】:WhyweusethecellIdentifier?为什么我们使用cellIdentifier?【发布时间】:2011-12-0807:47:06【问题描述】:-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPathstaticNSString 查看详情

为啥使用 IntrospectionFragmentMatcher?

】为啥使用IntrospectionFragmentMatcher?【英文标题】:WhyuseIntrospectionFragmentMatcher?为什么使用IntrospectionFragmentMatcher?【发布时间】:2018-10-3106:44:01【问题描述】:是否有任何理由使用IntrospectionFragmentMatcher来确定从接口和联合字段返... 查看详情

为啥有人应该在 git commit 之前使用 git add?或者为啥有人应该使用 git add 呢?

】为啥有人应该在gitcommit之前使用gitadd?或者为啥有人应该使用gitadd呢?【英文标题】:Whyshouldsomeoneusegitaddbeforegitcommit?ORwhyshouldsomeoneusegitaddatall?为什么有人应该在gitcommit之前使用gitadd?或者为什么有人应该使用gitadd呢?【发布... 查看详情

为啥操作系统不能使用整个 64 位进行寻址?为啥只有 48 位?

】为啥操作系统不能使用整个64位进行寻址?为啥只有48位?【英文标题】:Whycan\'tOSuseentire64-bitsforaddressing?Whyonlythe48-bits?为什么操作系统不能使用整个64位进行寻址?为什么只有48位?【发布时间】:2011-03-1406:29:34【问题描述】... 查看详情

为啥使用@PostConstruct?

】为啥使用@PostConstruct?【英文标题】:Whyuse@PostConstruct?为什么使用@PostConstruct?【发布时间】:2011-03-2507:23:58【问题描述】:在托管bean中,@PostConstruct在常规Java对象构造函数之后调用。为什么我要使用@PostConstruct来通过bean进行... 查看详情

为啥 DefaultMessageListenerContainer 不应该使用 CachingConnectionFactory?

】为啥DefaultMessageListenerContainer不应该使用CachingConnectionFactory?【英文标题】:WhyDefaultMessageListenerContainershouldnotuseCachingConnectionFactory?为什么DefaultMessageListenerContainer不应该使用CachingConnectionFactory?【发布时间】:2014-03 查看详情

为啥对 HttpResponseCache 使用反射?

】为啥对HttpResponseCache使用反射?【英文标题】:WhyusereflectionforHttpResponseCache?为什么对HttpResponseCache使用反射?【发布时间】:2014-06-0809:49:36【问题描述】:在HttpResponseCache的documentation中有一段:使用早期版本这个类是在Android4.0... 查看详情

为啥要使用 SerializeField?

】为啥要使用SerializeField?【英文标题】:WhyshouldIuseSerializeField?为什么要使用SerializeField?【发布时间】:2018-11-0714:58:22【问题描述】:刚开始学习C#和Unity,有一点不习惯:为什么以及何时应该使用[SerializeField]?尽管使用了[Seri... 查看详情

为啥使用 GoogleAPIClient 请求位置更新?

】为啥使用GoogleAPIClient请求位置更新?【英文标题】:WhyuseGoogleAPIClienttorequestlocationupdates?为什么使用GoogleAPIClient请求位置更新?【发布时间】:2016-09-2617:42:31【问题描述】:我注意到可以(至少)以两种不同的方式请求位置更... 查看详情

为啥刷新令牌更安全?如果刷新令牌也可能被盗,为啥我们还要使用它?

】为啥刷新令牌更安全?如果刷新令牌也可能被盗,为啥我们还要使用它?【英文标题】:Whyisrefreshtokenismoresecure&whydoweuserefreshtokenifitcanalsobestolen?为什么刷新令牌更安全?如果刷新令牌也可能被盗,为什么我们还要使用它?... 查看详情

为啥不使用指针变量

】为啥不使用指针变量【英文标题】:Whydonotusepointervariable为什么不使用指针变量【发布时间】:2013-04-1708:14:53【问题描述】:我是iOS应用开发的新手。我正在关注一个教程,该教程在BIDAppDelegate.m中有以下代码sn-p-(BOOL)application:(... 查看详情

为啥不能多次使用 MPMoviePlayerController?

】为啥不能多次使用MPMoviePlayerController?【英文标题】:WhyisitnotpossibletousetheMPMoviePlayerControllermorethanonce?为什么不能多次使用MPMoviePlayerController?【发布时间】:2009-10-1017:08:17【问题描述】:在MonoTouch中,我们在MoviePlayer示例中遇... 查看详情

为啥要使用 ExpressionVisitor?

】为啥要使用ExpressionVisitor?【英文标题】:WhywouldIwanttouseanExpressionVisitor?为什么要使用ExpressionVisitor?【发布时间】:2017-05-1621:59:13【问题描述】:我从MSDN关于Howto:ModifyExpressionTrees的文章中知道ExpressionVisitor应该做什么。它应该... 查看详情

为啥允许我们更改“const”限定变量的值?为啥允许使用指针,但不允许赋值?

】为啥允许我们更改“const”限定变量的值?为啥允许使用指针,但不允许赋值?【英文标题】:Whyareweallowedtochangevaluesof"const"qualifiedvariables?Whypointersareallowedforthis,butnotassignment?为什么允许我们更改“const”限定变量的值?... 查看详情

为啥使用分配不好?

】为啥使用分配不好?【英文标题】:Whyisusingassignbad?为什么使用分配不好?【发布时间】:2013-07-0717:14:57【问题描述】:这篇文章(LazyevaluationinR–isassignaffected?)涵盖了一些共同点,但我不确定它是否能回答我的问题。当我很久... 查看详情