How to instantiate a class in Objective-C that don

2019-01-23 14:24发布

问题:

Given this:

Person.h:

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

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?

回答1:

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.

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.

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:

@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).



回答2:

You must:

  1. Inherit from NSObject,
  2. Do a "poor man's" class with your own mallocs, etc, or
  3. Use Objective-C++ and create a C++ class.

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



回答3:

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

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.

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.

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:

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)

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

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

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

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



回答4:

you can't..

Alloc and new ..copy init all these methods are defined in 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