如何在iOS上强制发布

mem*_*emo 6 memory-management objective-c ios automatic-ref-counting

我是ARC的新手,但了解它是如何工作的,我正在尝试它.我在iOS上,所以内存是一个严重的问题.

我有一个包含大量数据的MyObject类.我想释放它,并加载一组新数据.

MyObject *object;
object = [[MyObject alloc] initWithData:folder1]; // load data from folder1

// later...
object = [[MyObject alloc] initWithData:folder2]; // load data from folder2
Run Code Online (Sandbox Code Playgroud)

这样可以正常工作而不会泄漏,我猜测ARC在新分配之前插入了[对象发布].我的问题是在分配新集合释放'object'中的数据,并且我的内存不足.我真正希望能做的是:

object = nil;

<function to pop the pool, wait till everything is deallocated>

object = [MyObject alloc] initWithData:folder2]; // load data from folder2
Run Code Online (Sandbox Code Playgroud)

但我不知道该怎么做.我可以在延迟后在一个执行选择器上运行新的分配,但感觉就像我在黑暗中拍摄并且有点黑客攻击.可能有一个正确的方法来做到这一点?

PS我试过寻找答案,但所有结果都是关于内存泄漏以及如何确保变量超出范围并将变量设置为nil等等.我的问题不在于此,更多的是时间问题.

更新
感谢您的回答,我已经尝试过了

object = nil;
object = [MyObject alloc] initWithData:folder2];
Run Code Online (Sandbox Code Playgroud)

它没有奏效.我不确定是否应该这样做.现在我明白了,这应该工作,但是我必须有别的东西抓着它的第二个的那部分.我在所有的init/dealloc方法中都有NSLog,我可以首先看到被调用的新类实例(MyObject的ivars)的所有内容,然后几乎立即(在几毫秒内),MyObject的dealloc其次是伊利亚斯的deallocs.我也尝试了@autorelease,但同样的事情发生了.

我在整个项目中搜索并粘贴了我认为可能与此相关的所有代码.

@interface AppDelegate : UIResponder <UIApplicationDelegate>;
    @property PBSoundSession *soundSession;
@end


//--------------------------------------------------------------
@implementation AppDelegate

// onTimer fired at 60Hz
-(void)onTimer:(NSTimer *) theTimer {
   [oscReceiver readIncoming]; // check incoming OSC messages
   // then do a bunch of stuff with _soundSession;
}
@end


//--------------------------------------------------------------
@implementation OscReceiver

-(void)readIncoming {
   AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

   // parse all incoming messages

   if(bLoadNewSoundBank) {
      NSString *newFolder = parseNewFolder();
      appDelegate.soundSession = nil;
      appDelegate.soundSession = [MyObject alloc] initWithData:newFolder];
   }
}

@end


//--------------------------------------------------------------
@implementation GuiController

// onTimer fired at 10Hz
-(void)onTimer:(NSTimer *) theTimer {
   PBSoundSession *soundSession = appDelegate.soundSession;
   // update gui with received values
}

@end
Run Code Online (Sandbox Code Playgroud)

我认为可能是GuiController :: onTimer中的'soundSession'局部变量在该方法的持续时间内持有旧的appDelegate.soundSession,但令我惊讶的是注释掉了所有的GUI代码(事实上禁用了定时器),没有区别.

有没有办法找到那个仍然持有我的appDelegate.soundSession的人?我在断点处设置了nil,但找不到任何有用的信息.我在分配模板中尝试了仪器,但在那里找不到任何有用的东西(可能因为我不知道在哪里看).

这就是我的分配跟踪的样子,你可以看到内存全部解除分配有点太晚了! 有效的XHTML.

Noa*_*oon 11

这可能不是ARC问题.您可以看到的是您的自动释放池不会很快耗尽 - 您的MyObject正在被释放,但是由于某些内部-retain/ -autorelease对,它加载的数据会被池保留.尝试将您的-initWithData:调用包装在一个@autoreleasepool块中,如下所示:

@autoreleasepool {
    object = [[MyObject alloc] initWithData:folder1];
    // do things
}
// later…
@autoreleasepool {
    object = [[MyObject alloc] initWitData:folder2];
    // do other things
}
Run Code Online (Sandbox Code Playgroud)

在将对象nil设置为其他内容之前,将对象设置为Gabriele建议的其他内容可能会导致编译器在第二个-alloc/ 之前插入适当的版本-initWithData:,但它可能已经足够智能 - 如果这不起作用,则很可能是自动释放池的事情.