首页 \ 问答 \ 可能的保留周期 - iOS /目标 - C.(Possible Retain Cycle — iOS/Objective - C)

可能的保留周期 - iOS /目标 - C.(Possible Retain Cycle — iOS/Objective - C)

我正在解析XML文件中的数据,并相信我已经找到了一个保留周期。 我不知道如何解决它。 简而言之,我正在解析一个块内的一堆浮动,导致我的内存使用量通过屋顶 - 它超过250 MB。 不好。 这是代码:

[TBXML iterateElementsForQuery:@"library_animations" fromElement:rootElement withBlock:^(TBXMLElement *anElement) {
        [self parseLibraryAnimationsElement:anElement];
}];

上面的方法调用以下方法:

- (void)parseLibraryAnimationsElement:(TBXMLElement *)element
{
    [TBXML iterateElementsForQuery:@"animation" fromElement:element withBlock:^(TBXMLElement *anElement) {
        TBXMLElement *extraElement = [TBXML childElementNamed:@"extra" parentElement:anElement];
        TBXMLElement *techniqueElement = [TBXML childElementNamed:@"technique" parentElement:extraElement];

        // grab float data
        **NSData *floatData = [self extractFloatArrayFromElement:techniqueElement];**

        // append data per animation ID
        NSString *key = [NSString stringWithFormat:@"#%@", [TBXML valueOfAttributeNamed:@"id" forElement:anElement]];
        [self.root.sortedAnimationKeys addObject:key];

        // use float data to store color information for this frame
        for (COLLADAMeshGeometry *geometry in self.root.geometries.allValues) {
            AGLKMesh *mesh = geometry.mesh;

            NSMutableData *dynamicColorData = [NSMutableData data];
            GLKVector3 *newColorInfo = (GLKVector3 *)[floatData bytes];

            // cycle through vertices for this mesh and use color float array information
            for (int i = 0; i < mesh.numberOfVertices; i++) {
                AGLKMeshVertex *staticVertex = [mesh vertexAtIndex:i];
                GLKVector3 newColor = newColorInfo[staticVertex->colorIndex];
                GLKVector4 color = GLKVector4Make(newColor.x, newColor.y, newColor.z, 1.0);

                [dynamicColorData appendBytes:&color length:sizeof(color)];
            }

            // get key and store in animation dictionary on the mesh
            [mesh.animationBufferDictionary setObject:dynamicColorData forKey:key];
        }
    }];

    // sort animation keys
    if (self.root.sortedAnimationKeys.count > 0) {
        [self.root.sortedAnimationKeys sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    }
}

** ... **之间的方法也在下面。 这是我认为问题所在。 字符串未正确释放。

- (NSData *)extractFloatArrayFromElement:(TBXMLElement *)element
{
    // element is <source>
    NSMutableData *floatData = [NSMutableData data];
    TBXMLElement *floatElement = [TBXML childElementNamed:@"float_array" parentElement:element];
    NSString *stringValues = [TBXML textForElement:floatElement];

    NSArray *values = [stringValues componentsSeparatedByString:@" "];
    for (NSString *value in values) {
        float floatValue = [value floatValue];
        [floatData appendBytes:&floatValue length:sizeof(floatValue)];
    }

    return floatData;
}

我说这是在这里的某个地方,因为当我使用Allocations Instrument时,我会得到大量的CFStrings,如下面的截图所示。 我不确定这是否是足够的信息,但如果有人能看到任何问题,请告诉我。 否则,我可以采取正确方向迈出的一步。 在此处输入图像描述

当我深入查看CFString(不可变)行时,它有许多行,这些行在[NSString componentsSeparatedByString:]中创建。


I am parsing data from a XML file and believe I've found a retain cycle. I don't have the best understanding how to fix it though. In short, I'm parsing out a bunch of floats within a block which leads to my memory usage going through the roof - it goes over 250 MB. Not good. Here is the code:

[TBXML iterateElementsForQuery:@"library_animations" fromElement:rootElement withBlock:^(TBXMLElement *anElement) {
        [self parseLibraryAnimationsElement:anElement];
}];

The method above calls the following method:

- (void)parseLibraryAnimationsElement:(TBXMLElement *)element
{
    [TBXML iterateElementsForQuery:@"animation" fromElement:element withBlock:^(TBXMLElement *anElement) {
        TBXMLElement *extraElement = [TBXML childElementNamed:@"extra" parentElement:anElement];
        TBXMLElement *techniqueElement = [TBXML childElementNamed:@"technique" parentElement:extraElement];

        // grab float data
        **NSData *floatData = [self extractFloatArrayFromElement:techniqueElement];**

        // append data per animation ID
        NSString *key = [NSString stringWithFormat:@"#%@", [TBXML valueOfAttributeNamed:@"id" forElement:anElement]];
        [self.root.sortedAnimationKeys addObject:key];

        // use float data to store color information for this frame
        for (COLLADAMeshGeometry *geometry in self.root.geometries.allValues) {
            AGLKMesh *mesh = geometry.mesh;

            NSMutableData *dynamicColorData = [NSMutableData data];
            GLKVector3 *newColorInfo = (GLKVector3 *)[floatData bytes];

            // cycle through vertices for this mesh and use color float array information
            for (int i = 0; i < mesh.numberOfVertices; i++) {
                AGLKMeshVertex *staticVertex = [mesh vertexAtIndex:i];
                GLKVector3 newColor = newColorInfo[staticVertex->colorIndex];
                GLKVector4 color = GLKVector4Make(newColor.x, newColor.y, newColor.z, 1.0);

                [dynamicColorData appendBytes:&color length:sizeof(color)];
            }

            // get key and store in animation dictionary on the mesh
            [mesh.animationBufferDictionary setObject:dynamicColorData forKey:key];
        }
    }];

    // sort animation keys
    if (self.root.sortedAnimationKeys.count > 0) {
        [self.root.sortedAnimationKeys sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    }
}

The method between ** ... ** is also below. This is where I believe the issue is. The strings aren't being deallocated properly.

- (NSData *)extractFloatArrayFromElement:(TBXMLElement *)element
{
    // element is <source>
    NSMutableData *floatData = [NSMutableData data];
    TBXMLElement *floatElement = [TBXML childElementNamed:@"float_array" parentElement:element];
    NSString *stringValues = [TBXML textForElement:floatElement];

    NSArray *values = [stringValues componentsSeparatedByString:@" "];
    for (NSString *value in values) {
        float floatValue = [value floatValue];
        [floatData appendBytes:&floatValue length:sizeof(floatValue)];
    }

    return floatData;
}

I say it's somewhere in here because when I'm using the Allocations Instrument I get a huge number of CFStrings as you can see in the screenshot below. I'm not sure if this is enough information or not, but if someone can see any issues let me know. Otherwise maybe there's a step in the right direction I can take. enter image description here

When I drill down into the CFString (immutable) line, it has a number of lines that these are created in [NSString componentsSeparatedByString:].


原文:https://stackoverflow.com/questions/19279322
更新时间:2023-07-30 11:07

最满意答案

像这样使用cin.fail() (而不仅仅是cin >> menuChoice; )(在这篇文章之后建模):

cin >> menuChoice;
if (cin.fail()) {
  cout << "Please enter a valid choice" << endl;
  cin.clear();
  cin.ignore();
  continue;
}
//Remove the cin.ignore() at this place!

有关更多详细信息,请参阅此SO线程


Use cin.fail() like this (instead of just cin >> menuChoice;) (modelled after this post):

cin >> menuChoice;
if (cin.fail()) {
  cout << "Please enter a valid choice" << endl;
  cin.clear();
  cin.ignore();
  continue;
}
//Remove the cin.ignore() at this place!

For more detailed info, see this SO thread

相关问答

更多
  • 你的while()条件应该是 while(gradesVector[i] < 0.0 || gradesVector[i] > 100.0)并使用此代码 for(vector::size_type i = 0; i < 15; i++) { int c=0; do { if(c!=0) //checking that we didnt entered loop for first time cout << "Invalid R ...
  • 在try块中,在你写之前 continue; 但在“您只能输入正数”之后,您应该提示用户输入另一行,并等待用户输入。 “continue”语句跳到循环结束并导致循环的第二部分不运行。 这就是循环无限期运行的原因。 In the try block, before you write continue; but after "You can only type positive numbers," you should prompt the User for another line of input, ...
  • while (scan.next() == "Y"); // Is checking for reference equality 在Java中进行对象比较时,使用equals() while (scan.next().equals("Y")); 或者,正如前面的答案指出的那样,您可以将字符与==运算符进行比较 while (scan.next() == "Y"); // Is checking for reference equality When doing object co ...
  • 问题是“scanf()”可能会在您的输入缓冲区中留下未读数据。 因此,“无限循环”。 另一个问题是你应该从scanf()验证返回值。 如果你期望一个整数值......并且scanf返回“0”项读取...那么你就知道出了什么问题。 这是一个例子: #include void discard_junk () { char c; while((c = getchar()) != '\n' && c != EOF) ; } int main (int argc, char ...
  • 测试条件超出了读取它的{和}的范围,因此将String answer的声明(小写)移动到do语句之前,以便我们可以在块之外对其进行测试(while指令不在其中并且是再次执行该块的条件)。 nextLine()返回并消耗相应的值,结果就是它。 String answer; do { System.out.println("Do you want to watch a movie?"); answer = scan.nextLine(); } while(!a ...
  • 所以这里有一些代码可以回答你的问题并帮助你入门。 但是,您的逻辑存在问题,这些问题与您之后将要解决的问题无关。 注意 :我在您的代码中添加了注释。 他们中的大多数都以“编辑:”开头,这样你就可以告诉我改变了什么。 我没有在所有情况下都使用这个前缀,因为其中一些是新代码而且显然是我的评论 import java.util.Scanner; public class InterestCalculator { public static void main(String[] args) { // E ...
  • 你可以做以下两件事之一: 在while循环结束时添加额外的检查: if(inp>10){ printf("error"); } 或者你可以避免额外的检查,同时牺牲一点可读性并改变你的while循环 while(inp>10 && printf("error")) 这是有效的,因为如果第一个语句为true,则printf()将不会因短路而执行,但如果为false,则printf()将在返回到循环顶部之前执行。 You could do one of two things: Add an extra ...
  • 像这样使用cin.fail() (而不仅仅是cin >> menuChoice; )(在这篇文章之后建模): cin >> menuChoice; if (cin.fail()) { cout << "Please enter a valid choice" << endl; cin.clear(); cin.ignore(); continue; } //Remove the cin.ignore() at this place! 有关更多详细信息,请参阅此SO线程 Use cin.fa ...

相关文章

更多

最新问答

更多
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)
  • 是否可以嵌套hazelcast IMaps?(Is it possible to nest hazelcast IMaps? And whick side effects can I expect? Is it a good Idea anyway?)
  • UIViewAnimationOptionRepeat在两个动画之间暂停(UIViewAnimationOptionRepeat pausing in between two animations)
  • 在x-kendo-template中使用Razor查询(Using Razor query within x-kendo-template)
  • 在BeautifulSoup中替换文本而不转义(Replace text without escaping in BeautifulSoup)
  • 如何在存根或模拟不存在的方法时配置Rspec以引发错误?(How can I configure Rspec to raise error when stubbing or mocking non-existing methods?)
  • asp用javascript(asp with javascript)
  • “%()s”在sql查询中的含义是什么?(What does “%()s” means in sql query?)
  • 如何为其编辑的内容提供自定义UITableViewCell上下文?(How to give a custom UITableViewCell context of what it is editing?)
  • c ++十进制到二进制,然后使用操作,然后回到十进制(c++ Decimal to binary, then use operation, then back to decimal)
  • 以编程方式创建视频?(Create videos programmatically?)
  • 无法在BeautifulSoup中正确解析数据(Unable to parse data correctly in BeautifulSoup)
  • webform和mvc的区别 知乎
  • 如何使用wadl2java生成REST服务模板,其中POST / PUT方法具有参数?(How do you generate REST service template with wadl2java where POST/PUT methods have parameters?)
  • 我无法理解我的travis构建有什么问题(I am having trouble understanding what is wrong with my travis build)
  • iOS9 Scope Bar出现在Search Bar后面或旁边(iOS9 Scope Bar appears either behind or beside Search Bar)
  • 为什么开机慢上面还显示;Inetrnet,Explorer
  • 有关调用远程WCF服务的超时问题(Timeout Question about Invoking a Remote WCF Service)