我认为我对objective-c的内存管理有一个很好的处理,但我无法弄清楚以下情况:
@protocol MyProtocol @end
@interface MyObject : NSObject { idreference; } @property (nonatomic, retain) id reference; @end
@implementation MyObject @synthesize reference; -(void) dealloc { [reference release]; [super dealloc]; } ... @end
这给了我一个" 警告:' - 发布'未在协议中找到 ".我可以安全地忽略这个错误吗?或者我在做一些可怕的错误?
是的,您可以安全地忽略此错误.声明为类型的对象id
可能不继承NSObject
(你不具备使用可可库在Objective-C编程还有其他根类甚至在可可等NSProxy
).因为retain
(和release
,autorelease
)声明中NSObject
,编译器无法知道,声明为类型的实例id
来响应这些消息.为了解决这个问题,Cocoa还定义了镜像API 的NSObject
协议NSObject
.如果您将协议声明为
@protocol MyProtocol@end
指示MyProtocol
扩展NSObject
协议,您将被设置.
通常,当您声明一个对象时,id
它会计算一个"任意"对象(这意味着Objective-C将允许您在id
没有警告的情况下从任何类或协议调用任何方法).
但是,当您声明一个对象时id
,其含义会发生变化.在这种情况下,您反而说:我只会SomeProtocol
在此对象上调用方法.
方法:
- (void)release;
在NSObject
协议中声明,但您已明确声明:我只会调用MyProtocol
方法.所以编译器会给你一个警告,告诉你你违背了自己的承诺.
因此,而不是:
idreference;
你应该真的声明:
idreference;
要么:
NSObjectreference;
因为NSObject
(类)实现NSObject
(协议).
要么:
id reference;
这是最广泛的一部分:让我在这个对象上调用任何东西,永远不要抱怨.
你也可以(巴里Wark的建议)有MyProtocol
包括NSObject
协议-虽然从设计的角度来看,你通常只能这样做,如果实现MyProtocol
一定使用手段NSObject
.通常情况下,我们只有做到这一点NSObject
,并MyProtocol
正在heritarily或语义上的联系.
关于NSObject
协议的一些信息:
您调用的所有内容在保留/释放/自动释放时必须实现此协议.正如你可以从中推断的那样:基本上所有东西都实现了NSObject
协议(即使有些东西不是从NSObject
基类中下来的).
另一个快速澄清:( NSObject
类)和NSObject
(协议)不是相同API的重新实现.它们分为以下几种:
NSObject(协议)实现了在一般意义上处理/检查现有对象所需的一切(retain/release,isEqual,class,respondsToSelector:等).
NSObject(类)实现了不太通用的方法:构造/销毁,线程集成,脚本集成.
所以在大多数情况下,协议是两者中更重要的.记住这个类包含了协议,所以如果你从NSObject下载,你就得到了这两个协议.