我有这段代码:
Entry.h
#import <Foundation/Foundation.h>
@interface Entry : NSObject {
id object;
SEL function;
}
@property (retain) id object;
@property (assign) SEL function;
-(Entry*) initWithObject:(id)object selector:(SEL)function;
@end
Entry.m
#import "Entry.h"
@implementation Entry
@synthesize object;
@synthesize function;
-(Entry*) initWithObject:(id)obj selector:(SEL)sel {
self = [super init];
[self setObject:obj];
[self setFunction:sel];
return self;
}
-(void) dealloc {
[super dealloc];
if ([self object] != nil)
[[self object] release];
}
@end
当我这样做时:
Entry *hej = [Entry alloc];
[hej release];
我明白了:
objc[2504]: FREED(id): message object sent to freed object=0xf5ecd0
Program received signal: “EXC_BAD_INSTRUCTION”.
我做错了什么?
(这个插件代码在堆栈溢出时不起作用,除非我做错了什么并且你不应该点击“代码示例”然后粘贴。)
答案 0 :(得分:7)
+alloc
仅分配内存。您需要-init
才能在该内存空间中实际创建对象。由于您只是分配内存而不是在那里创建对象,因此在一块内存上调用-release
会给您一个错误。此外,您希望[super dealloc]
调用显示在-dealloc
方法的末尾。改变这两件事,以下内容应该有效:
Entry *hej = [[Entry alloc] init];
[hej release];
答案 1 :(得分:3)
这里有两个问题:
1)你需要检查self = [super init]
是否没有返回nil。典型的用法是使用条件包装初始化代码:
if ((self = [super init]) != nil) {
// initialize the object...
}
2)但是你遇到的问题是实例化你的对象:你应该这样做:
Entry *hej = [[Entry alloc] initWithObject:myObj selector:mySelector];
(假设您想要浏览刚刚定义的自定义初始化程序... 否则只使用默认的init方法。)但是'alloc'必须后跟一个init。
Entry *hej = [[Entry alloc] init]; // will do the trick...
答案 2 :(得分:1)
首先,你需要一个init来配合你的。其次,在dealloc中,您在致电[super dealloc]
后向自己发送消息。你不能这样做。最后的解除分配应该在最后。
答案 3 :(得分:1)
我还建议改变:
if ([self object] != nil)
[[self object] release];
为:
[self setObject:nil];
它的代码和功能相同。 =)
答案 4 :(得分:0)
您的代码有很多问题。我会尝试通过它们。
首先,最好在属性名称中使用不同的ivar名称,以便清楚地显示每个名称。 Apple通常使用下划线前缀,但任何前缀都可以。
@interface Entry : NSObject {
id _object;
SEL _function;
}
@property (retain) id object;
@property (assign) SEL function;
@synthesize object = _object;
@synthesize function = _function;
接下来,您没有使用标准的init模板(虽然这通常不会产生任何影响)。
-(Entry*) initWithObject:(id)obj selector:(SEL)sel {
self = [super init];
if (self != nil) {
// initializations
}
return self;
}
接下来,Apple(出于好的理由)建议不要在init / dealloc中使用getter / setter。所以你的init将是:
-(Entry*) initWithObject:(id)obj selector:(SEL)sel {
self = [super init];
if (self != nil) {
_object = [obj retain];
_object = sel;
}
return self;
}
接下来,在[super dealloc]之后你的对象被破坏了,所以你不能在那之后引用self(以及你的ivars),所以你的dealloc应该是这样的:
-(void) dealloc {
// your deallocations
[super dealloc];
}
此外,如上所述,Apple建议您不要在dealloc例程中使用setter或getter,因此您的释放最初应如下所示:
if (_object != nil)
[_object release];
但更进一步,Objective C允许(和Cocoa鼓励)将方法发送到nil什么都不做。这与其他大多数消息都会导致崩溃的语言形成鲜明对比,但它是Objective C / Cocoa的工作方式,你需要习惯它。所以你的释放实际上只是:
[_object release];
最后,alloc只为你的对象分配内存,你必须初始化它,所以初始化将是这样的:
Entry *hej = [[Entry alloc] initWithObject:myobj selector:@selector(mymethod)];