我是Objective-C的新手,但在C和C ++方面拥有丰富的经验。我注意到的第一件事就是基本教程中存在一个真正的空白,因为所有人都假设您正在为iPhone或Mac开发并使用Cocoa。我没有使用Cocoa或Gnustep。要点:
作为开始的一个简单示例,我正在尝试包装C的文件I / O功能。我的代码以 File.h
#include <objc/Object.h>
#include <stdio.h>
@interface File:Object
{
FILE *pFile;
char *path;
}
@property FILE *pFile;
@property char *path;
- (void)new;
- (void)OpenReadText:(const char*)var1;
- (void)release;
@end
和File.m
#include "File.h"
@implementation File
@synthesize pFile, path;
- (void)new
{
self = [super init];
}
- (void)release
{
fclose(pFile);
[super release];
}
- (void)OpenReadText:(char*)var1
{
path = var1;
pFile = fopen(path,"r");
}
@end
然后是main.m
#include <stdio.h>
#import <objc/Object.h>
#include "File.h"
int main(void) {
File *Fileobj = [File new];
[Fileobj OpenReadText:"File.h"];
[Fileobj release];
}
编译器给我一个警告,我的对象“可能不响应'-release'”。然后,当运行程序时会导致运行时错误:“无法识别释放。此应用程序已请求运行时终止”..等等。
我猜我正在制作一个简单的新手错误,但在哪里?或许还有什么遗失?我希望有人能指出我正确的方向。感谢。
如果已经问过这个qst那么参考也会这样做。我确实试图找到参考但没有运气。
关注:
将发布方法更改为
- (void)release
{
fclose(pFile);
[super free];
}
它似乎有效。显然,free
会识别出object.h
。
答案 0 :(得分:4)
正如其他人所说,在没有Foundation框架的情况下使用Objective-C是不寻常的。但是,Object
类应该实现release
,retain
等。在Apple的Objective-C运行时中包含(但未使用)的Object
类当然包含这些基本方法。< / p>
假设您的Object
类确实包含这些基本方法,那么您的类在实现时会遇到一些问题。
首先,您创建了一个new
实例方法,只需调用[super init]
即可。按惯例,new
方法是一个类方法,它是调用alloc
和init
来创建和初始化对象的简写。 new
在Apple的Object
课程中定义。它实现为:
+ (id)new
{
id newObject = (*_alloc)((Class)self, 0);
Class metaClass = self->isa;
if (class_getVersion(metaClass) > 1)
return [newObject init];
else
return newObject;
}
请注意,此方法是一种类方法,由+
代替-
表示。 GNUStep按如下方式实现new
:
+ new
{
return [[self alloc] init];
}
使用new
的惯用方法是:
File *obj = [File new];
这实际上是你所做的,但是,这是调用类方法new
而不是实例方法new
。
如果您想拨打new
方法,则必须致电:
File *obj = [[File alloc] new];
但正如其他人所说,你需要归还你的对象。删除新方法对您的实现没有影响,因为它当前没有被调用。
其次,您已在覆盖fclose
方法中调用release
。这是错误的,当然在Apple的Object
实现中,GNUstep似乎有所不同。 release
可以在一个对象的实例上多次调用。 retain
和release
用于递增/递减对象保留计数。仅当保留计数达到零时,才应关闭文件句柄。通常情况下,您可以在基金会内以fclose
方式拨打dealloc
。 dealloc
是Objective-C的析构函数方法。 dealloc
应该类似于:
- (void)dealloc
{
fclose(pFile);
[super dealloc];
}
但是,dealloc
似乎没有在Apple或GNUstep的Object
类中实现。正如您在问题中指出的那样,free
方法似乎是一个析构函数。
似乎用等效的dealloc
方法替换上面的free
方法可以作为析构函数,例如:
- (void)free
{
fclose(pFile);
[super free];
}
Apple的Object
实现包含retain
和release
方法,但GNUstep实现却没有。这两种实现都不包含dealloc
方法。
Apple和GNUstep的Object.m
和NSObject.m
的实现可以在以下位置找到:
Apple Object.m:http://opensource.apple.com/source/objc4/objc4-532.2/runtime/Object.m
GNUstep Object.m:https://github.com/gnustep/gnustep-libobjc/blob/master/Object.m
Apple NSObject.mm:http://opensource.apple.com/source/objc4/objc4-532.2/runtime/NSObject.mm
GNUstep NSObject.m:https://github.com/gnustep/gnustep-base/blob/master/Source/NSObject.m
答案 1 :(得分:2)
release
班上是否定义了Object
?如果不是,那么请致电
[super release];
不起作用。 (在cocoa中,release是NSObject
的成员;您的Object
类可能有也可能没有,实际上保留/释放引用计数可能根本不存在。)
您应确认您的基类包含通过super
调用的所有方法。
答案 2 :(得分:1)
正如@ xlc0212指出的那样,内存管理的引用计数风格包含在NSObject中。
NSObject是Cocoa,CocoaTouch和GnuStep的CoreFoundation库的一部分。我会说你需要链接到CoreFoundation。
我读过的一本关于纯Objective-C(不一定是Cocoa)的书是由Steven G Kochan撰写的“Objective-C 2.0编程”。