在 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<MyProtocol>
类型的对象可能不会从 NSObject
继承(您没有有使用 Cocoa 库在 Objective-C 中编程,即使在 Cocoa 中也有其他根类,例如 @ 987654323@)。由于retain
(和release
、autorelease
)在NSObject
中声明,编译器无法知道声明为id<MyProtocol>
类型的实例响应了这些消息。为了解决这个问题,Cocoa 还定义了 NSObject
protocol,它反映了 NSObject
API。如果您将协议声明为
@protocol MyProtocol <NSObject>
@end
表明MyProtocol
扩展了NSObject
协议,您将被设置。
【讨论】:
【参考方案2】:通常,当您将一个对象声明为id
时,它会计算一个“任何”对象(这意味着Objective-C 将允许您从id
上的任何类或协议调用任何方法而不会发出警告)。
但是,当您将对象声明为id<SomeProtocol>
时,含义会发生变化。在这种情况下,您的意思是:我只会在此对象上调用 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
时才这样做。通常,我们仅在 NSObject
和 MyProtocol
以遗传或语义链接时才这样做。
关于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 服务