在 Objective-C (iphone) 中,如何管理“@protocol”引用的内存?

Posted

技术标签:

【中文标题】在 Objective-C (iphone) 中,如何管理“@protocol”引用的内存?【英文标题】:In objective-C (iphone), how do I manage the memory of '@protocol' references? 【发布时间】:2010-10-25 17:19:17 【问题描述】:

我认为我对 Objective-c 的内存管理有很好的处理,但我无法弄清楚以下情况:


@protocol MyProtocol
@end

@interface MyObject : NSObject 
    id<MyProtocol> reference;

@property (nonatomic, retain) id<MyProtocol> reference;
@end

@implementation MyObject 
@synthesize reference;
-(void) dealloc 
    [reference release];
    [super dealloc];

...
@end

这给了我一个“警告:在协议中找不到'-release'”。 我可以安全地忽略此错误吗?还是我做错了什么?

【问题讨论】:

【参考方案1】:

是的,您可以放心地忽略此错误。声明为 id&lt;MyProtocol&gt; 类型的对象可能不会从 NSObject 继承(您没有使用 Cocoa 库在 Objective-C 中编程,即使在 Cocoa 中也有其他根类,例如 @ 987654323@)。由于retain(和releaseautorelease)在NSObject 中声明,编译器无法知道声明为id&lt;MyProtocol&gt; 类型的实例响应了这些消息。为了解决这个问题,Cocoa 还定义了 NSObject protocol,它反映了 NSObject API。如果您将协议声明为

@protocol MyProtocol <NSObject>
@end

表明MyProtocol 扩展了NSObject 协议,您将被设置。

【讨论】:

【参考方案2】:

通常,当您将一个对象声明为id 时,它会计算一个“任何”对象(这意味着Objective-C 将允许您从id 上的任何类或协议调用任何方法而不会发出警告)。

但是,当您将对象声明为id&lt;SomeProtocol&gt; 时,含义会发生变化。在这种情况下,您的意思是:我只会在此对象上调用 SomeProtocol 方法。

方法:

- (void)release;

NSObject 协议中声明,但您已明确声明:我只会调用MyProtocol 方法。所以编译器会给你一个警告,告诉你你违背了自己的承诺。

因此,而不是:

id<MyProtocol> reference;

您实际上应该声明:

id<MyProtocol, NSObject> reference;

或:

NSObject<MyProtocol> reference;

因为NSObject(类)实现了NSObject(协议)。

或:

id reference;

这是最广泛的:让我在这个对象上调用任何东西,从不抱怨。

您也可以(如 Barry Wark 所建议的)让MyProtocol 包含NSObject 协议——尽管从设计的角度来看,通常只有在实现MyProtocol 必然意味着使用NSObject 时才这样做。通常,我们仅在 NSObjectMyProtocol 以遗传或语义链接时才这样做。


关于NSObject 协议的一点信息:

您调用 retain/release/autorelease 的所有内容都必须实现此协议。你可以由此推断:基本上所有东西都实现了NSObject 协议(尽管有些东西不是来自NSObject 基类)。

另一个快速澄清:NSObject(类)和NSObject(协议)不是同一个 API 的重新实现。它们的拆分如下:

NSObject(协议)实现了处理/检查一般意义上的现有对象所需的一切(保留/释放、isEqual、类、responsToSelector:等)。

NSObject(类)实现的通用方法较少:构造/销毁、线程集成、脚本集成。

所以在大多数意义上,协议是两者中更重要的一个。请记住,该类包含协议,因此如果您从 NSObject 继承,您将得到两者。

【讨论】:

【参考方案3】:

改变

@property (nonatomic, retain) id<MyProtocol> reference;

@property (nonatomic, assign) id<MyProtocol> reference;

为什么要保留实现协议的对象?您所需要的只是一个指向对象的指针,我们可以通过它调用协议中声明的方法。

【讨论】:

你不能假设他不需要在没有更多上下文的情况下保留对象。

以上是关于在 Objective-C (iphone) 中,如何管理“@protocol”引用的内存?的主要内容,如果未能解决你的问题,请参考以下文章

在 Objective-C (iphone) 中,如何管理“@protocol”引用的内存?

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

UIButtons 的 2D 数组不起作用(Objective-C/iPhone 开发)

在 iPhone 上使用 Objective-C 使用 WCF Web 服务

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

Objective-c用iphone 4s插入数据