菜鸟教程小白 发表于 2022-12-13 07:41:58

iphone - NSFetchedResultsController numberOfObjects 在设备上运行时返回附加(重复)


                                            <p><p>我已经使用 NSFetchedResultsController 实现了一个 UITableView 来从 sqllite 数据库加载数据。我从设备下载了数据库到模拟器,所以两者都是一样的。</p>

<p>我观察到奇怪的行为,当在模拟器上运行时,tableview 填充了正确数量的单元格(在初始基本情况下:一个单元格);但是,当我在设备上运行相同的代码时,numberOfObjects 返回 2,并且 tableview 显示两个(相同/重复)单元格。</p>

<p>当我检查 sqllite 文件时,其中确实只有 1 个对象/行...</p>

<p>我按照示例代码进行了实现,并没有做任何特别的事情。</p>

<pre><code>- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSInteger count = [ count];

    if (count == 0) {
      count = 1;
    }

    return count;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger numberOfRows = 0;

    if ([ count] &gt; 0) {
      id &lt;NSFetchedResultsSectionInfo&gt; sectionInfo = [ objectAtIndex:section];
      numberOfRows = ;
    }

    NSLog(@&#34;SwoopListTableViewController::numberOfRowsInSection - numberOfRows:%d&#34;, numberOfRows);
    return numberOfRows;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Dequeue or if necessary create a SwoopTableViewCell, then set its Swoop to the Swoop for the current row.            
    static NSString *SwoopCellIdentifier = @&#34;SwoopCellIdentifier&#34;;

    SwoopTableViewCell *SwoopCell = (SwoopTableViewCell *);
    if (SwoopCell == nil) {
      SwoopCell = [[ initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SwoopCellIdentifier] autorelease];
      SwoopCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    ;
    return SwoopCell;
}
</code></pre>

<p>和</p>

<pre><code>- (NSFetchedResultsController *)fetchedResultsController {
    // Set up the fetched results controller if needed.
    NSLog(@&#34;SwoopListTableViewController::fetchedResultsController - started&#34;);

    if (fetchedResultsController == nil) {

      if (managedObjectContext == nil)
      {
            managedObjectContext = [(SwoopAppDelegate *)[ delegate] managedObjectContext];
            NSLog(@&#34;SwoopListTableViewController::fetchedResultsController - set managedObjectContext&#34;);
      }

      // Create the fetch request for the entity.
      NSFetchRequest *fetchRequest = [ init];

      NSEntityDescription *entity = ;
      ;

      NSSortDescriptor *sortDescriptor = [ initWithKey:@&#34;creationDate&#34; ascending:NO];
      NSArray *sortDescriptors = [ initWithObjects:sortDescriptor, nil];
      ;

      NSFetchedResultsController *aFetchedResultsController = [ initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@&#34;Root&#34;];
      aFetchedResultsController.delegate = self;
      self.fetchedResultsController = aFetchedResultsController;

      ;
      ;
      ;
      ;
    }

    return fetchedResultsController;
}
</code></pre>

<p>我很困惑为什么相同的代码和相同的数据库会在模拟器(按预期工作)与设备(3GS - 显示重复的表格单元格)上表现出不同的行为。任何人都可以帮助/解释/提供一些关于我应该看什么的见解吗?</p>

<p>非常感谢,
埃里克</p>

<p>** <strong><em>编辑 1:</em></strong> ** 我对 NSCoreData 和 NSFetchedResultsController 做了更多的调试。似乎 fetchRequest 确实从 managedContext 返回了一个重复的对象。这是代码和相应的控制台输出:</p>

<p> Controller 代码:</p>

<pre><code>- (void)viewDidLoad {   
    NSError *error = nil;
    if (![ performFetch:&amp;error]) {
      NSLog(@&#34;Unresolved error %@, %@&#34;, error, );
      abort();
    }      
    id &lt;NSFetchedResultsSectionInfo&gt; sectionInfo = [ objectAtIndex:0];
    NSLog(@&#34;SwoopListTableViewController::viewDidLoad - sectionInfo objects:%@&#34;, );      
}
</code></pre>

<p>控制台输出:</p>

<pre><code>2011-05-14 17:54:53.388 Swoop SwoopListTableViewController::viewDidLoad - sectionInfo objects:(
    &#34;&lt;Swoop: 0x187d60&gt; (entity: Swoop; id: 0x186480 &lt;x-coredata://A9FF2CC0-77EE-4EFF-A3A6-5F085AA9CCAC/Swoop/p2&gt; ; data: &lt;fault&gt;)&#34;,
    &#34;&lt;Swoop: 0x187d60&gt; (entity: Swoop; id: 0x186480 &lt;x-coredata://A9FF2CC0-77EE-4EFF-A3A6-5F085AA9CCAC/Swoop/p2&gt; ; data: &lt;fault&gt;)&#34;,
    &#34;&lt;Swoop: 0x188180&gt; (entity: Swoop; id: 0x143a60 &lt;x-coredata://A9FF2CC0-77EE-4EFF-A3A6-5F085AA9CCAC/Swoop/p1&gt; ; data: &lt;fault&gt;)&#34;
)
</code></pre>

<p>我觉得奇怪的是 sectionInfo 中的前两个对象都具有相同的内存地址“0x187d60”并且都具有相同的 x-coredata 'path':“//A9FF2CC0-77EE-4EFF-A3A6-5F085AA9CCAC/Swoop/p2"...谁能解释一下这是什么意思,或者可能发生了什么?</p>

<p>谢谢,
埃里克</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>在对 NSCoreData 进行了更多阅读和挖掘之后,问题似乎是由于设备上内存管理方式的特殊性(我会假设相同的内存限制/管理将应用于模拟器,但我猜两者之间存在差异)——特别是,如果在内存不足警告下卸载 View ,则在再次重新加载 View 时将执行提取,这可能导致重复条目。</p>

<p>我发现以下链接中描述的问题/解决方案解决了我遇到的问题:</p>

<p> <a href="http://blog.engledew.com/post/560601132/duplicate-nsmanagedobject-with" rel="noreferrer noopener nofollow">Duplicate NSManagedObject with NSFetchedResultsController</a> </p>

<p>另一方面,通过将此参数传递给应用程序,了解能够启用不同级别的 NSCoreData 日志记录也很有帮助:</p>

<pre><code>-com.apple.CoreData.SQLDebug 1
</code></pre>

<p>在这里阅读更多:</p>

<p>从 Apple 开发者库中,查看“核心数据疑难解答:<a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdTroubleshooting.html#//apple_ref/doc/uid/TP40002320-SW21" rel="noreferrer noopener nofollow">Debugging Fetching</a>”</p>

<p>要通过 xcode 添加参数,请参阅本页 <a href="http://www.meandmark.com/xcodetips.html" rel="noreferrer noopener nofollow">http://www.meandmark.com/xcodetips.html</a> 上的“为命令行程序提供启动参数” </p></p>
                                   
                                                <p style="font-size: 20px;">关于iphone - NSFetchedResultsController numberOfObjects 在设备上运行时返回附加(重复),我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/5975019/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/5975019/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iphone - NSFetchedResultsController numberOfObjects 在设备上运行时返回附加(重复)