iPhone/Cocoa Touch - 多线程问题(Stanford Presence 3 项目)

发布于 2024-08-08 13:06:22 字数 966 浏览 8 评论 0原文

我一直在解决名为 Presence 3 的斯坦福大学免费 iPhone 课程项目(在斯坦福网站上找到:www.stanford.edu/class/cs193p/cgi-bin/downloads.php,它为用户从 Twitter 中提取数据,这些数据存储在加载数据时,UIActivityIndi​​cator(旋转器)可见。加载数据后,TableView 会在列表中显示用户及其照片,并且当我成功单击用户的单元格时,会显示用户状态。显示带有照片的 TableView,并在单击时显示另一个带有状态的视图控制器,但是当我添加到微调器中时,我的程序崩溃了,我的程序几乎与 ThreadedFlickrTableView 示例项目相同,该项目也可以在同一位置找到。上面的链接(抱歉,我是新用户,只能发布一个链接),该链接有效,我在代码中放置了断点以查看问题出在哪里,我发现程序在加载单元格时崩溃了。 cellForRowAtIndexPath 方法,特别是当它从适当的数组 (followeesPhotoURLs) 检索照片时。这是因为数组是空的 - 照片从未下载过,因为主线程决定在专用于从互联网下载的线程完成执行(它确实开始执行)之前执行单元格加载方法。

我查看了该课程的审核员讨论组页面,发现其他人也有同样的问题,但该帖子从未解决该问题,我发送电子邮件无济于事: http://groups.google.com/group/iphone-appdev-auditors/browse_thread/thread/ccfc6ae99b4cf45d/ef1b8935e749c7c2?hl=zh-CN&lnk=gst&q=presence3#ef1b8935e749c7c2

I have been solving the Stanford free iPhone course project called Presence 3 (found on the stanford site: www.stanford.edu/class/cs193p/cgi-bin/downloads.php, which pulls data from twitter for users, which are stored in a plist. A UIActivityIndicator (spinner) is visible while the data is loading. Once the data has been loaded, a TableView displays the users in a list with their photos, and user statuses show up when a user's cell is clicked. I can successfully display the TableView with the photos and bring up another view controller with statuses when clicked. But when I add in the spinner, my program crashes. I set up my program almost identically to the ThreadedFlickrTableView example project, which can also be found at the same link above (sorry, I'm a new user and can only post one link), which works. I put breakpoints in my code to see where the problem was, and I found that the program crashes when it is loading a cell in the cellForRowAtIndexPath method, specifically when it is retrieving the photo from the appropriate array (followeesPhotoURLs). This is because the array is empty - the photos were never downloaded since the main thread decides to execute the cell-loading method before the thread dedicated to downloading from the internet finishes executing (it does start executing).

I looked on the auditors discussion group page for the course and found that someone else had the same problem, but the thread never resolved the issue, and I emailed to no avail:
http://groups.google.com/group/iphone-appdev-auditors/browse_thread/thread/ccfc6ae99b4cf45d/ef1b8935e749c7c2?hl=en&lnk=gst&q=presence3#ef1b8935e749c7c2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一袭白衣梦中忆 2024-08-15 13:06:22

我的 UITableView 的第一条规则是永远不要报告未准备好的部分或行(带有某些内容,即使只是占位符),因为它每次都会崩溃。

加载资源时,旋转器正在旋转。因此,您正在等待可能已准备好也可能尚未准备好的资源,因为您不知道后台进程的确切状态。如何在主线程中设置一个值来指示事情尚未准备好。然后,当辅助线程完成加载内容时,您可以执行performSelectorOnMainThread 来导致某些主线程函数设置值以指示您可以继续。在该值显示“继续”之前,您的主线程不会尝试访问辅助线程可能接触的那些值。也许您的单元格将显示“正在加载”或类似内容,直到数据准备好为止,或者您只需在单元格准备就绪时添加它们。

还有一件事 - 只有主线程可以触摸 UI。除非明确说明,否则 UIKit 中的任何内容都不是线程安全的。进度指示器的更改必须由主线程处理,它应该启动指示器并停止它(可能当您的辅助线程通知“完成”时,如上所述)。

My first rule of UITableView is never report sections or rows that aren't ready (with something, even if only a placeholder) because it will crash every time.

The spinner is spinning while the resource is loading. So you are waiting for a resource that may or may not be ready because you don't know the exact state of your background process. How about setting a value in your main thread indicating that things are not ready. Then when your secondary thread finishes loading things you can do performSelectorOnMainThread to cause some main thread function to set the value to indicate you can proceed. Until the value says proceed, your main thread does not try to access those values the secondary thread might be touching. Maybe your cells will display "loading" or similar until the data is ready, or you will just add cells as they become ready.

One more thing - ONLY the main thread can touch the UI. Nothing in UIKit is thread safe unless explicitly stated. The changes to the progress indicator must be handled by the main thread, it should start the indicator and stop it (probably when your secondary thread notifies "done", as above).

暗恋未遂 2024-08-15 13:06:22

我今天刚刚完成此工作,以下是我观察到的事件顺序:

  1. 您的表视图将加载任何内容,因为您的数组不包含任何内容
  2. 您的线程将检索 Twitter 数据
  3. 您的表视图将使用 Twitter 数据刷新 [self .tableView reloadData]

如果您像我一样,您会尝试使用类似的内容来设置用户名,

cell.textLabel.text = [[userInfo objectAtIndex:indexPath.row] valueForKey:@"name"];

我认为因为它非常具体,所以应用程序确实会尝试查找它,如果没有,则不会返回 null找到任何东西,与示例中的代码不同,

cell.text = [photoNames objectAtIndex:indexPath.row];

...因此您的应用程序在第一次尝试使用空数组加载数据时会出错。

我解决这个问题的方法是创建一个数组,从一开始就从属性列表加载用户名,这样我就知道我的内容数组中应该有多少条目。关键部分是在设置单元格之前创建一个条件,以便您知道您拥有所需的所有信息,例如...

    // Set up the cell...
if ([userInfo count] == [userList count]) {

userInfo 是我的字典数组,其中包含来自 Twitter 的数据。

userList 是我的属性列表中的值数组。

I just finished working through this today and here's the sequence of events that I observed:

  1. Your table view will load up with nothing because your arrays contain nothing
  2. Your thread will go and retrieve Twitter data
  3. Your table view will be refreshed with the Twitter data [self.tableView reloadData]

If you're like me, you try to set the user name using something similar to

cell.textLabel.text = [[userInfo objectAtIndex:indexPath.row] valueForKey:@"name"];

I think that because it is very specific, the application really tries to look for it and doesn't return null if it doesn't find anything, unlike the code in the example which is

cell.text = [photoNames objectAtIndex:indexPath.row];

...so your application errors out the first time it tries to load data with empty arrays.

The way I worked around this is to create an array that loads the user names from the property list at the very beginning so I know how many entries there should be in my array of content. The key part is to create a condition before setting up your cell so that you know you have all the information that you need such as...

    // Set up the cell...
if ([userInfo count] == [userList count]) {

userInfo is my array of dictionaries with the data that comes from Twitter.

userList is my array of values from the property list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文