Аргументы сохраняются после завершения NSIvocationOperation? - PullRequest
0 голосов
/ 06 марта 2012

Отредактировано после того, как я получил ответ:
- На самом деле нет утечек памяти. Объект, добавленный в NSInvocationOperation, будет сохранен и также освобожден, как и ожидалось.

Почему после добавления объекта в NSInvocationOperation он сохраняется, а также после , когда операция завершена, сохраняется еще раз?

А как мне предотвратить утечки памяти?

Внизу есть мой пример кода. Я извиняюсь, если вас так раздражает такой код, но я просто хотел быть уверен, что ничего не пропустил. Кроме того, комментарии рядом с NSLogs показывают их вывод.

Весь мой AppDelegate.m:

//
//  AppDelegate.m
//  BRISI
//
//  Created by Aleksa Topic on 2/22/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;

- (void)dealloc
{
  [_window release];
  [super dealloc];
}

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NSObject *a = [[NSObject alloc] init];
  NSLog(@"a1: %d", a.retainCount); // a1: 1

  NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
  NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                      initWithTarget:self
                                            selector:@selector(s:)
                                              object:a];
  NSLog(@"a2: %d", a.retainCount); // a2: 2

  [a release];
  NSLog(@"a3: %d", a.retainCount); // a3: 1

  [operationQueue addOperation:operation];
  [operation release];
  NSLog(@"a4: %d", a.retainCount); // a4: 1

  NSLog(@"oper1: %@", operation); // oper1: <NSInvocationOperation: 0x6a3f7d0>

  NSLog(@"a5: %d", a.retainCount); // a5: 1
  NSLog(@"a5: %d", a.retainCount); // a5: 1
  NSLog(@"a5: %d", a.retainCount); // a5: 1
  NSLog(@"a5: %d", a.retainCount); // a5: 2
  NSLog(@"a5: %d", a.retainCount); // a5: 2
  NSLog(@"a5: %d", a.retainCount); // a5: 2
  NSLog(@"a5: %d", a.retainCount); // a5: 2
  NSLog(@"a5: %d", a.retainCount); // a5: 2

  // And here I get: "Thread 1: Program received signal: "EXC_BADACCESS"."
  NSLog(@"oper2: %@", operation);

  self.window = [[[UIWindow alloc]
                  initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
  // Override point for customization after application launch.
  self.window.backgroundColor = [UIColor whiteColor];
  [self.window makeKeyAndVisible];
  return YES;
}

- (void)s:(NSArray *)a
{
  NSLog(@"a (s:): %d", a.retainCount); // a (s:): 1
  NSLog(@"a (s:): %d", a.retainCount); // a (s:): 1
  NSLog(@"a (s:): %d", a.retainCount); // a (s:): 1
}

@end

А вот вывод, если вы хотите сравнить:

GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".sharedlibrary apply-load-rules all
Attaching to process 7927.
2012-03-06 16:19:20.712 BRISI[7927:207] a1: 1
2012-03-06 16:19:20.715 BRISI[7927:207] a2: 2
2012-03-06 16:19:20.715 BRISI[7927:207] a3: 1
2012-03-06 16:19:20.716 BRISI[7927:207] a4: 1
2012-03-06 16:19:20.717 BRISI[7927:207] oper1: <NSInvocationOperation: 0x6858da0>
2012-03-06 16:19:20.717 BRISI[7927:1e03] a (s:): 1
2012-03-06 16:19:20.717 BRISI[7927:207] a5: 1
2012-03-06 16:19:20.718 BRISI[7927:1e03] a (s:): 1
2012-03-06 16:19:20.718 BRISI[7927:207] a5: 1
2012-03-06 16:19:20.718 BRISI[7927:1e03] a (s:): 1
2012-03-06 16:19:20.719 BRISI[7927:207] a5: 1
2012-03-06 16:19:20.719 BRISI[7927:207] a5: 2
2012-03-06 16:19:20.720 BRISI[7927:207] a5: 2
2012-03-06 16:19:20.720 BRISI[7927:207] a5: 2
2012-03-06 16:19:20.721 BRISI[7927:207] a5: 2
2012-03-06 16:19:20.721 BRISI[7927:207] a5: 2
Current language:  auto; currently objective-c
(gdb) 

1 Ответ

0 голосов
/ 06 марта 2012

Всякий раз, когда я имею дело с хитрым набором операций сохранения / освобождения, я проверяю, переопределяю ли соответствующие методы:

@interface RetainCountChecker : NSObject

@end

@implementation RetainCountChecker

-(oneway void)release{
    [super release];
    NSLog(@"release - retainCount = %d", [self retainCount]);
}

-(id)retain{
    id result = [super retain];

    NSLog(@"retain - retainCount = %d", [self retainCount]);
    return result;
}

-(void)dealloc{
    [super dealloc];
}

@end

Установка точек останова в методах сохранения, освобождения и освобождения позволяет увидеть, когдаи как каждый из них называется.В вашем случае NSInvocationOperation автоматически освобождает внутренний объект NSInvocation.Оборачивание рассматриваемого кода в блок

@autorelease{

}

приведет к освобождению "a" перед возвращением -application: didFinishLaunchingWithOptions: метод.

...