如何在Objective-C中实例化没有从NSObject继承的类

时间:2022-03-12 07:50:12

Given this:

鉴于这种:

Person.h:

Person.h:

@interface Person 
{
}
- (void) sayHello;
@end

Person.m:

Person.m:

#import "Person.h"

@implementation Person 

- (void)sayHello 
{
    printf("%s", "Steve");
}

@end

How do you instantiate the Person? I tried this:

如何实例化这个人?我试着这样的:

Person *p = [Person new];

That doesn't work, nor this:

这是行不通的,

Person *p = [Person alloc];

[UPDATE]

(更新)

I forgot to tell, I already tried inheriting from NSObject, the new and alloc works. I'm just curious if we can instantiate a class that doesn't inherit from NSObject?

我忘了说,我已经尝试了继承NSObject,新的和alloc工作。我只是好奇我们能否实例化一个没有从NSObject继承的类?

4 个解决方案

#1


28  

You absolutely can do so. Your class simply needs to implement +alloc itself, the way that NSObject does. At base, this just means using malloc() to grab a chunk of memory big enough to fit the structure defining an instance of your class.

你绝对可以这么做。您的类只需要实现+alloc本身,就像NSObject那样。在base中,这仅仅意味着使用malloc()获取足够大的内存块,以适应定义类实例的结构。

Reference-counted memory management would also be nice (retain/release); this is actually part of the NSObject protocol. You can adopt the protocol and implement these methods too.

引用计数内存管理也不错(保留/释放);这实际上是NSObject协议的一部分。您可以采用协议并实现这些方法。

For reference, you can look at the Object class, which is a root ObjC class like NSObject, that Apple provides in its open source repository for the Objective-C runtime:

作为参考,您可以查看Object类,它是一个根ObjC类,比如NSObject,苹果在其面向Objective-C运行时的开源存储库中提供的:

@implementation Object 

// Snip...

+ alloc
{
    return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
}

// ...

- init
{
    return self;
}

// And so on...

That being said, you should think of NSObject as a integral part of the ObjC runtime. There's little if any reason to implement your own root class outside of curiosity, investigation, or experimentation (which should, however, not be discouraged at all).

也就是说,您应该将NSObject看作ObjC运行时的一个组成部分。除了好奇心、调查和实验之外,几乎没有什么理由去实现你自己的根类。

#2


4  

You must:

你必须:

  1. Inherit from NSObject,
  2. 从NSObject继承,
  3. Do a "poor man's" class with your own mallocs, etc, or
  4. 和你自己的mallocs做一个“穷人”班,等等,还是
  5. Use Objective-C++ and create a C++ class.
  6. 使用objective - c++创建一个c++类。

Of course, neither of the other two fit into Objective-C storage management, and their call protocols, etc, are different.

当然,其他两个都不适合Objective-C存储管理,以及它们的调用协议等等。

#3


3  

There is (very likely) no good reason to not want to inherit from NSObject, but there are many good reasons to do so.

(很可能)没有好的理由不希望继承NSObject,但是有很多好的理由这样做。

I would be curious as to your reason for why you don't want to inherit from NSObject. I would guess it stems from a lack of knowledge rather than a real need.

我很好奇你为什么不想继承NSObject。我猜这是由于缺乏知识,而不是真正的需要。

But even without knowing that reason: Don't do it. It's so hard to do this well in a way that it still plays nice with other Objective-C classes as to be virtually impossible.

但即使不知道这个原因,也不要去做。要做到这一点非常困难,以至于它在其他Objective-C类中仍然运行良好,这几乎是不可能的。

Anyway, you're instantiating your objects in a way that hides what's really done. While in Java, you usually create instances via the default constructor method new, in Objective-C you instantiate by calling alloc on the class and then init on the instance:

不管怎样,你用一种隐藏真正做了什么的方式实例化你的对象。而在Java中,你通常通过默认的构造函数方法new创建实例,在Objective-C中,你在类上调用alloc,然后在实例上init:

Person *aPerson = [[Person alloc] init];

(It is possible to just use Person new, but I wouldn't do it because it hides what's really done from you)

(使用Person new是可能的,但我不会这么做,因为它隐藏了你真正做了什么)

You implement your class such that you inherit from NSObject and then, if necessary, write your own init method.

实现您的类,以便从NSObject继承,然后,如果需要,编写自己的init方法。

If you want to log to the console, use NSLog:

如果您想要登录到控制台,请使用NSLog:

NSLog(@"Hello %@", @"Steven");

(@"" is a special constructor for a NSString. Strings in Objective-C are not byte arrays, but objects.)

(@""是NSString的特殊构造函数。Objective-C中的字符串不是字节数组,而是对象。

#4


-6  

you can't..

你不能. .

Alloc and new ..copy init all these methods are defined in NSObject..

Alloc和新. .所有这些方法都是在NSObject中定义的。

You cannot also create your own since apple does not provide NSObject implementation class..so you have to inherit from NSObject or its subclass so that you can initialize your class

由于苹果不提供NSObject实现类,您也不能创建自己的。所以你必须从NSObject或它的子类继承这样你才能初始化你的类

#1


28  

You absolutely can do so. Your class simply needs to implement +alloc itself, the way that NSObject does. At base, this just means using malloc() to grab a chunk of memory big enough to fit the structure defining an instance of your class.

你绝对可以这么做。您的类只需要实现+alloc本身,就像NSObject那样。在base中,这仅仅意味着使用malloc()获取足够大的内存块,以适应定义类实例的结构。

Reference-counted memory management would also be nice (retain/release); this is actually part of the NSObject protocol. You can adopt the protocol and implement these methods too.

引用计数内存管理也不错(保留/释放);这实际上是NSObject协议的一部分。您可以采用协议并实现这些方法。

For reference, you can look at the Object class, which is a root ObjC class like NSObject, that Apple provides in its open source repository for the Objective-C runtime:

作为参考,您可以查看Object类,它是一个根ObjC类,比如NSObject,苹果在其面向Objective-C运行时的开源存储库中提供的:

@implementation Object 

// Snip...

+ alloc
{
    return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
}

// ...

- init
{
    return self;
}

// And so on...

That being said, you should think of NSObject as a integral part of the ObjC runtime. There's little if any reason to implement your own root class outside of curiosity, investigation, or experimentation (which should, however, not be discouraged at all).

也就是说,您应该将NSObject看作ObjC运行时的一个组成部分。除了好奇心、调查和实验之外,几乎没有什么理由去实现你自己的根类。

#2


4  

You must:

你必须:

  1. Inherit from NSObject,
  2. 从NSObject继承,
  3. Do a "poor man's" class with your own mallocs, etc, or
  4. 和你自己的mallocs做一个“穷人”班,等等,还是
  5. Use Objective-C++ and create a C++ class.
  6. 使用objective - c++创建一个c++类。

Of course, neither of the other two fit into Objective-C storage management, and their call protocols, etc, are different.

当然,其他两个都不适合Objective-C存储管理,以及它们的调用协议等等。

#3


3  

There is (very likely) no good reason to not want to inherit from NSObject, but there are many good reasons to do so.

(很可能)没有好的理由不希望继承NSObject,但是有很多好的理由这样做。

I would be curious as to your reason for why you don't want to inherit from NSObject. I would guess it stems from a lack of knowledge rather than a real need.

我很好奇你为什么不想继承NSObject。我猜这是由于缺乏知识,而不是真正的需要。

But even without knowing that reason: Don't do it. It's so hard to do this well in a way that it still plays nice with other Objective-C classes as to be virtually impossible.

但即使不知道这个原因,也不要去做。要做到这一点非常困难,以至于它在其他Objective-C类中仍然运行良好,这几乎是不可能的。

Anyway, you're instantiating your objects in a way that hides what's really done. While in Java, you usually create instances via the default constructor method new, in Objective-C you instantiate by calling alloc on the class and then init on the instance:

不管怎样,你用一种隐藏真正做了什么的方式实例化你的对象。而在Java中,你通常通过默认的构造函数方法new创建实例,在Objective-C中,你在类上调用alloc,然后在实例上init:

Person *aPerson = [[Person alloc] init];

(It is possible to just use Person new, but I wouldn't do it because it hides what's really done from you)

(使用Person new是可能的,但我不会这么做,因为它隐藏了你真正做了什么)

You implement your class such that you inherit from NSObject and then, if necessary, write your own init method.

实现您的类,以便从NSObject继承,然后,如果需要,编写自己的init方法。

If you want to log to the console, use NSLog:

如果您想要登录到控制台,请使用NSLog:

NSLog(@"Hello %@", @"Steven");

(@"" is a special constructor for a NSString. Strings in Objective-C are not byte arrays, but objects.)

(@""是NSString的特殊构造函数。Objective-C中的字符串不是字节数组,而是对象。

#4


-6  

you can't..

你不能. .

Alloc and new ..copy init all these methods are defined in NSObject..

Alloc和新. .所有这些方法都是在NSObject中定义的。

You cannot also create your own since apple does not provide NSObject implementation class..so you have to inherit from NSObject or its subclass so that you can initialize your class

由于苹果不提供NSObject实现类,您也不能创建自己的。所以你必须从NSObject或它的子类继承这样你才能初始化你的类