iPhone - Objective-C - 内存泄漏与 initWithArray

Posted

技术标签:

【中文标题】iPhone - Objective-C - 内存泄漏与 initWithArray【英文标题】:iPhone - Objective-C - Memory Leak with initWithArray 【发布时间】:2011-02-13 03:03:45 【问题描述】:

我正在使用下面的代码来设置我的两个NSArray ivars:

问题是,我在以下几行中不断出现内存泄漏:

followingFriendsArray = [[NSArray alloc] initWithArray:friend.Following];
followerFriendsArray = [[NSArray alloc] initWithArray:friend.Followers];

这不是从现有NSArray 项目设置 ivars 的正确方法吗?任何帮助,将不胜感激。我也试过autorelease上面两行,但是当我用另一种方法实际访问它们时,我得到一个错误,它们已经被释放了。

我在下面包含了我的接口和实现代码:

接口.h:

NSArray *followingFriendsArray;
NSArray *followerFriendsArray;

@property (nonatomic, retain) NSArray *followingFriendsArray;
@property (nonatomic, retain) NSArray *followerFriendsArray;

实现.m:

- (void)handlerGetFollowingInformation:(id)value 
    BOOL success = [Utility checkWebServiceErrors:value controller:self.navigationController];

    if (success) 
        Friend *friend = (Friend *)value;

        followingFriendsArray = [[NSArray alloc] initWithArray:friend.Following];
        followerFriendsArray = [[NSArray alloc] initWithArray:friend.Followers];
    

这就是我需要访问数组的方式:

- (void)followersButtonTapped:(id)sender 
    FollowingVC *fvc = [[FollowingVC alloc] initWithNibName:@"FollowingViewController" bundle:nil];

    fvc.friends = followerFriendsArray;

    [self.navigationController pushViewController:fvc animated:YES];
    [fvc release];

我像往常一样通过以下方式释放我的两个 ivars:

- (void)viewDidUnload 
    self.followingFriendsArray = nil;
    self.followerFriendsArray = nil;
    [super viewDidUnload];


- (void)dealloc 
    [followingFriendsArray release];
    [followerFriendsArray release];
    [super dealloc];

我的意思是代码工作得很好,只是我在运行“泄漏”性能工具时担心所说的内存泄漏。

【问题讨论】:

你释放了这两个数组吗?顺便说一句,你为什么使用可变数组? 我已将它们更改为 NSArray 的。我像往常一样在 View Controller 中以通常的 dealloc 方式释放它们。 【参考方案1】:

好的

在这种情况下你不应该使用自动释放,但你必须通过调用来释放数组:

[followingFriendsArray release];
[followerFriendsArray release];

你可以做到的:

    当您不再需要使用它们时。 在 .m 文件的 dealloc 方法中。

选项 2 看起来像这样 -

- (void)dealloc 
[followingFriendsArray release];
[followerFriendsArray release];
[super dealloc];

顺便说一句- 如果您在创建数组(添加/删除对象)后不操作数组,则应使用不可变数组(NSArray)。 祝你好运

【讨论】:

谢谢你,我照常在 dealloc 方法中释放它们。我只是想修复“Leaks Profiler”中发生的内存泄漏。只要我在dealloc中释放它们就可以将它们记录为泄漏吗?这就是我感到困惑的地方。【参考方案2】:

您的方法handlerGetFollowingInformation 正在为followingFriendsArrayfollowerFriendsArray 分配新值,而不释放以前的内容。如果您在同一个实例上多次调用此方法,则会发生泄漏。

【讨论】:

【参考方案3】:

CRD 是正确的,数组没有在 handlerGeFollowingInformation 方法中释放,但修复可能是矫枉过正。您需要做的是使用 self. 以便调用 setter 方法,该方法会自动执行此操作。你应该看起来像这样:

- (void)handlerGetFollowingInformation:(id)value 
    BOOL success = [Utility checkWebServiceErrors:value controller:self.navigationController];

    if (success) 
        Friend *friend = (Friend *)value;

        self.followingFriendsArray = [[NSArray alloc] initWithArray:friend.Following];
        self.followerFriendsArray = [[NSArray alloc] initWithArray:friend.Followers];
    

容易修复,但很难发现,我一遍又一遍地遇到这个问题,尤其是当我开始释放属性时。

-安迪

【讨论】:

注意:很抱歉忘记发现您还需要释放阵列,或者您可以使用 [NSArray arrayWithArray:find.Following] 创建阵列。 谢谢安迪,我想我会选择 [NSArray arrayWithArray:] 因为它比不必担心释放数组要容易得多。这样做有什么缺点或问题吗?我认为这就像使用 [NSArray array] 初始化一个数组,对吗? 如果我没记错的话,[NSArray array*] 方法和 [[[NSArray alloc] init*]autorelease] 方法是一样的,只是你不必担心内存管理的问题。创建它们(* 表示任何附加名称,如“WithArray”)。有许多对象提供了像 NSDictionary 等这样的静态便利方法,我也喜欢它们。但是再一次记住使用“自我”。当你想使用属性设置方法时。

以上是关于iPhone - Objective-C - 内存泄漏与 initWithArray的主要内容,如果未能解决你的问题,请参考以下文章

iPhone - Objective-C - 内存泄漏与 initWithArray

Xcode 内存警告 - 无法加载任何 Objective-C 类信息

如何以编程方式在 iPhone 中查找可用内存?

iPhone(Objective-c)和Java之间的AES区别

如何用 Objective-C 判断 iPhone 是不是连接到 wifi 网络?

在 UITextField 键盘中启用“返回按钮”(objective-c/iphone)