【问题标题】:A question regarding object release关于对象释放的问题
【发布时间】:2025-12-02 02:00:02
【问题描述】:

以下代码来自 Apple 的 GKRocket iPhone 演示应用:

- (void) peerListDidChange:(SessionManager *)session;
{
    NSArray *tempList = peerList;
    peerList = [session.peerList copy];
    [tempList release];
    [self.tableView reloadData]; 
}

我是目标 c 的新手,想知道 tempList 是否真的需要发布?我的直觉告诉我不是因为它没有保留指针。也许我没有看到全貌。

如果确实需要发布,请有更多经验的人解释原因吗?

谢谢!

【问题讨论】:

    标签: iphone objective-c cocoa-touch


    【解决方案1】:

    只是猜测。我以前没有使用过那个示例项目。

    创建一个指向旧peerList 数组的新指针,称为tempList

    NSArray *tempList = peerList;
    

    代码复制session.peerList 并将peerList 指针分配给该新副本:

    peerList = [session.peerList copy];
    

    旧的peerList,实际上现在由tempList 指向,然后可以安全释放:

    [tempList release];
    

    如果您立即分配[session.peerList copy];,旧数组将不再有保留的指针,如果它没有自动释放,则会发生内存泄漏。

    如果你已经分配了tempList 但没有释放它,它会因为同样的原因泄漏内存,但tempList 的目的纯粹是为了让程序知道当你调用release 时要释放什么。

    【讨论】:

    • 哦,我明白为什么现在需要发布了。谢谢!
    • 这样做不是更有意义吗:if(peerList) [peerList release]; peerList = [session.peerList 副本];
    【解决方案2】:

    这个项目的最新版本实际上在代码中的这一点上崩溃了。 session.peerList 是 NSMutableArray - 应用程序在尝试将其分配给 tempList 时崩溃。我修改了代码以阻止崩溃。这是 peerList 的声明:

    @interface GameLobbyController : UITableViewController <UITableViewDelegate, UITableViewDataSource, SessionManagerLobbyDelegate, UIAlertViewDelegate> {
    NSMutableArray  *peerList;
    UIAlertView *alertView;
    SessionManager *manager;}
    

    这是新版本的 peerListDidChange 方法:

    - (void) peerListDidChange:(SessionManager *)session;{
    peerList = session.peerList;
    [self.tableView reloadData];}
    

    不确定,但我认为所有 tempList 代码只是为了处理从可变数组到固定数组的切换。显然我不明白为什么 peerList 属性是固定的而不是可变的如此重要。欢迎所有的cmets。

    【讨论】:

    • 如果 peerList 指向的不是自动释放的东西,可能会发生内存泄漏。
    • 谢谢 - 我已将其修改为: NSArray *tempPeerList = [session.peerList copy]; peerList = tempPeerList;由于 ARC,它仍然不允许我使用“释放”