代码之家  ›  专栏  ›  技术社区  ›  Lawrence

内存管理和性能选择器背景:

  •  12
  • Lawrence  · 技术社区  · 15 年前

    哪一个是对的?这是:

    NSArray* foo = [[NSArray alloc] initWithObjects:@"a", @"b", nil];
    [bar performSelectorInBackground:@selector(baz:) withObject:foo];
    
    - (void)baz:(NSArray*)foo {
        ...
        [foo release];
    }
    

    或:

    NSArray* foo = [[[NSArray alloc] initWithObjects:@"a", @"b", nil] autorelease];
    [bar performSelectorInBackground:@selector(baz:) withObject:foo];
    
    - (void)baz:(NSArray*)foo {
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
        ...
        [pool release];
    }
    

    我知道第一种模式有效,但是Clang抱怨它,所以我想知道是否有更好的模式可以使用。

    我会“试一试”第二个,但有自动租赁,谁知道是否有 EXC_BAD_ACCESS 意味着你做得对或者你只是运气好…

    2 回复  |  直到 15 年前
        1
  •  24
  •   Teemu Kurppa    15 年前

    首先是错误的。

    PerformSelectorInBackground:WithObject:在执行任务之前保留BAR和FOO。因此,您应该在创建FOO时自动释放它,并让performselectorinbackground:withobject负责其余部分。见 documentation

    后者是正确的,因为您在创建时自动释放foo。您在BAZ中创建的自动释放池与foo内存管理的正确性无关。自动释放对象需要自动释放池 里面 BAZ的池分配和释放,根本不涉及foo的保留计数。

        2
  •  2
  •   Duncan Babbage    13 年前

    现在的正确方法实际上是:

    NSArray* foo = [[[NSArray alloc] initWithObjects:@"a", @"b", nil] autorelease];
    [bar performSelectorInBackground:@selector(baz:) withObject:foo];
    
    - (void)baz:(NSArray*)foo {
        @autoreleasepool {
            ...
        }
    }