Ios 我是不是错过了ARC?

Ios 我是不是错过了ARC?,ios,xcode,memory-leaks,automatic-ref-counting,Ios,Xcode,Memory Leaks,Automatic Ref Counting,我正在为iOS5开发一个大规模的应用程序,在xcode中使用ARC。这个系统似乎工作得很好,除了当我试图取消分配一个接口时。我正在使用一个名为WhirlyGlobe的框架在first view控制器中创建一个3D交互式球体 当我切换视图控制器(在我拥有的4个视图控制器之间)时,我注意到用于视图控制器和globe的内存没有被释放。所有其他视图控制器(仅使用简单视图和图像)都可以很好地释放它们的内存,但地球仍然驻留在内存中。当导航回地球仪时,由于“GLSMLoadTextureLevel Buffe

我正在为iOS5开发一个大规模的应用程序,在xcode中使用ARC。这个系统似乎工作得很好,除了当我试图取消分配一个接口时。我正在使用一个名为WhirlyGlobe的框架在first view控制器中创建一个3D交互式球体

当我切换视图控制器(在我拥有的4个视图控制器之间)时,我注意到用于视图控制器和globe的内存没有被释放。所有其他视图控制器(仅使用简单视图和图像)都可以很好地释放它们的内存,但地球仍然驻留在内存中。当导航回地球仪时,由于“GLSMLoadTextureLevel Buffer”中的1mb分配,我的内存几乎增加了10mb

继续我的问题-在ARC处于活动状态时,我还能做些什么来帮助释放我的对象吗?我注意到我的viewDidUnload和dealloc方法根本没有被调用,而且我可以触发任何东西的唯一方法是使用ViewDidEnglish(这显然不理想)-请参见下面的:

- (void)clear
{
[[NSNotificationCenter defaultCenter] removeObserver:self];

if (self.layerThread)
{
    [self.layerThread cancel];
    while (!self.layerThread.isFinished)
        [NSThread sleepForTimeInterval:0.001];
}

self.glView = nil;
self.sceneRenderer = nil;

if (theScene)
{
    delete theScene;
    theScene = NULL;
}
self.theView = nil;
self.texGroup = nil;

self.layerThread = nil;
self.earthLayer = nil;
self.vectorLayer = nil;
self.labelLayer = nil;
self.interactLayer = nil;

self.pinchDelegate = nil;
self.panDelegate = nil;
self.tapDelegate = nil;
self.longPressDelegate = nil;
self.rotateDelegate = nil;
}

- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"dealloc - viewDidDisappear");
    [self clear];
}
我将不再需要的一切设置为零。这是最好的做法吗

地球仪设置代码: [超级视图下载]

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

// Set up an OpenGL ES view and renderer
EAGLView *ev = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, 824, self.view.frame.size.height)];
self.glView = ev;
self.sceneRenderer = [[SceneRendererES1 alloc] init];
UIColor *whiteC = [UIColor whiteColor];
[sceneRenderer setClearColor:whiteC];
glView.renderer = sceneRenderer;
glView.frameInterval = 2;  // 60 fps (2)
[self.view addSubview:glView];
self.view.backgroundColor = [UIColor blackColor];
self.view.opaque = YES;
self.view.autoresizesSubviews = YES;
//glView.frame = self.view.bounds;
glView.frame = CGRectMake(275, GLOBE_HEIGHT_FIX, 768, SCREEN_HEIGHT+STATUS_BAR_HEIGHT); // was 260 x
glView.backgroundColor = [UIColor whiteColor];
self.view.backgroundColor = [UIColor whiteColor]; // red for debug

// Create the textures and geometry, but in the right GL context
[sceneRenderer useContext];

self.texGroup = [[TextureGroup alloc] initWithInfo:[[NSBundle mainBundle] pathForResource:@"bdGlobe_info" ofType:@"plist"]];

// Need an empty scene and view
theScene = new WhirlyGlobe::GlobeScene(4*texGroup.numX,4*texGroup.numY);
self.theView = [[WhirlyGlobeView alloc] init];
[theView setFarPlane:5.0];
[theView setHeightAboveGlobe:GLOBE_HEIGHT_VIEW];
if (globeShouldAnimate) glView.alpha = 1.0;

// Need a layer thread to manage the layers
self.layerThread = [[WhirlyGlobeLayerThread alloc] initWithScene:theScene];

// Earth layer on the bottom
self.earthLayer = [[SphericalEarthLayer alloc] initWithTexGroup:texGroup];
[self.layerThread addLayer:earthLayer];

// Set up the vector layer where all our outlines will go
self.vectorLayer = [[VectorLayer alloc] init];
[self.layerThread addLayer:vectorLayer];

// General purpose label layer.
self.labelLayer = [[LabelLayer alloc] init];
[self.layerThread addLayer:labelLayer];

self.interactLayer = [[InteractionLayer alloc] initWithVectorLayer:self.vectorLayer labelLayer:labelLayer globeView:self.theView
                                                       countryShape:[[NSBundle mainBundle] pathForResource:@"10m_admin_0_map_subunits" ofType:@"shp"]
                                                         oceanShape:[[NSBundle mainBundle] pathForResource:@"10m_geography_marine_polys" ofType:@"shp"]
                                                        regionShape:[[NSBundle mainBundle] pathForResource:@"10m_admin_1_states_provinces_shp" ofType:@"shp"]]; 
self.interactLayer.maxEdgeLen = [self.earthLayer smallestTesselation]/10.0;
[self.layerThread addLayer:interactLayer];

// Give the renderer what it needs
sceneRenderer.scene = theScene;
sceneRenderer.view = theView;

// Wire up the gesture recognizers
self.panDelegate = [PanDelegateFixed panDelegateForView:glView globeView:theView];
self.tapDelegate = [WhirlyGlobeTapDelegate tapDelegateForView:glView globeView:theView];
self.longPressDelegate = [WhirlyGlobeLongPressDelegate longPressDelegateForView:glView globeView:theView];

// Kick off the layer thread
// This will start loading things
[self.layerThread start];

这只是个传闻,但也可能是类似的情况

我只是遇到了这样一种情况,在ARC中,我的对象从未被释放,即使它们是以静态方式访问的(例如,
[SingletonThing instance].thing
),因为自动释放池没有被释放。其原因是在自己的线程上运行一个奇怪的无止境循环。为封闭代码放置一个单独的
@autorelease


另一方面,即使您的一个(或libs)对象将
UIView
作为子视图,我认为您的UIViewController将永远不会
viewDidUnload
,因此永远不会解除锁定。我必须以经验来检验这一点。

这是一个轶事,但可能是类似的情况

我只是遇到了这样一种情况,在ARC中,我的对象从未被释放,即使它们是以静态方式访问的(例如,
[SingletonThing instance].thing
),因为自动释放池没有被释放。其原因是在自己的线程上运行一个奇怪的无止境循环。为封闭代码放置一个单独的
@autorelease


另一方面,即使您的一个(或libs)对象将
UIView
作为子视图,我认为您的UIViewController将永远不会
viewDidUnload
,因此永远不会解除锁定。我必须根据经验进行检查。

您可以使用分配工具进行检查。使用heap shot,您可以在应用程序生命周期的不同时间点标记堆,并在每个快照的时间点比较构成内存中当前分配的对象图。这将有助于您缩小保留内容和保留人的范围。

您可以使用分配工具进行此操作。使用heap shot,您可以在应用程序生命周期的不同时间点标记堆,并在每个快照的时间点比较构成内存中当前分配的对象图。这将有助于您缩小保留内容和保留对象的范围。

确保调用了
-(void)viewdidegase:(BOOL)animated

如果你使用

[self.view addSubview:yourViewController.view]

[yourViewController.view从SuperView移除]

然后将不会调用
viewdide消失:
viewdide出现:

这些回调将仅被调用 在IOS 5中使用
presentViewController:
时 或
presentModalViewController:
并在IOS 5中解除ViewControllerInitiated:
dismissModalViewControllerAnimated:
或者使用
UINavigationController
显示和关闭视图控制器

确保调用了
-(void)viewdidenerge:(BOOL)animated

如果你使用

[self.view addSubview:yourViewController.view]

[yourViewController.view从SuperView移除]

然后将不会调用
viewdide消失:
viewdide出现:

这些回调将仅被调用 在IOS 5中使用
presentViewController:
时 或
presentModalViewController:
并在IOS 5中解除ViewControllerInitiated:
dismissModalViewControllerAnimated:

或者使用
UINavigationController
显示和关闭您的viewController

我在使用堆快照后发现了问题(感谢Mark Adams)-结果表明我没有使两个代理成为弱实体,因此在更改视图控制器时没有释放它们。默认强代理保持常驻


多亏了这些建议,它们都为我指明了正确的方向:)

我在使用堆快照后发现了问题(多亏了Mark Adams)-事实证明,我没有让两个代理成为弱实体,因此在更改视图控制器时,它们没有被释放。默认强代理保持常驻


感谢所有的建议,它们都为我指明了正确的方向:)

您在应用程序上运行了泄漏工具吗?我的第一个倾向是检查WhirlyGlobe是否有泄漏。我已经运行了泄漏仪器-没有任何泄漏,只是每次打开globe部分时1mb内存分配的巨大跳跃。。。如果我弹出视图控制器并将其设置为nil,整个部分不应该被释放吗?您可以使用分配工具来实现这一点。使用heap shot,您可以在应用程序生命周期的不同时间点标记堆,并在每个快照的时间点比较构成内存中当前分配的对象图。“这将有助于你缩小被保留的内容和被谁保留的范围。”马克·亚当斯如果你把它作为一个答案,我会的