2 mapmapm MapMapM 于 2013.08.06 15:25 提问

无法初始化类对象-XCode

执行文件如下:

   @implementation Utils    
   +(id)alloc
   {
         return [self instance];
   }
   +(Utils *)instance
   {
        static Utils *utils = nil;
        if (!utils) {
           utils = [self init];
        }
        return utils;
   }
  -(Utils *)init
  {
       self = [super init];
       if (self) {
           mConst = [Constants instance];
           mCONT_REGEXP = [mConst CONT_REGEXP];
       }
       return self;
   }

在调用[Utils instance];时报错:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[Utils<0xbff54> init]: cannot init a class object.'

3个回答

zhanglei5415
zhanglei5415   Rxr 2013.08.06 16:28

看了你上面的代码,可以看出,你对“对象”的创建的过程一点也不了解。
对象也可以称之为类的实例,可以把类比喻成“模子”,而对象就是通过这个“模子”制造出来的具体产品。而对象的创建过程就是:
1、由alloc静态方法创建对象时,cocoa会从应用程序的虚拟地址空间上为该对象分配足够的内存。cocoa会遍历该对象所有的成员变量,通过成员变量的类型来计算所需占用的内存
cocoa除了上面提到的申请了一块足够大的内存外,还做了以下3件事:

. 将该新对象的引用计数(Retain Count)设置成1。
. 将该新对象的isa成员变量指向它的类对象。
. 将该新对象的所有其它成员变量的值设置成零。(根据成员变量类型,零有可能是指nil或Nil或0.0)

2、 init方法
大部分情况下,我们都不希望所有成员变量都是零,所以init方法会做真正的初使化工作,让对象的成员变量的值符合我们程序逻辑中的初始化状态。

所以一般的alloc方法是不允许用户自己去重写,你所可以自己实现的方法是init方法。一个单例类的简单实现应该是这样:

@implementation Utils    
 static Utils *_instance = nil;
   +(Utils *)instance
   {
        if (_instance==nil) {
           _instance = [[self alloc] init];
        }
        return _instance;
   }

  -(id)init
  {
       self = [super init];
       if (self) {
           mConst = [Constants instance];
           mCONT_REGEXP = [mConst CONT_REGEXP];
       }
       return self;
   }

@end
u013172558
u013172558   2013.12.16 12:31

将该新对象的引用计数(Retain Count)设置成1。
. 将该新对象的isa成员变量指向它的类对象。
. 将该新对象的所有其它成员变量的值设置成零。

Kakalapa1986
Kakalapa1986   2013.08.06 16:10
+ (id)sharedInstance;
{
    static dispatch_once_t onceToken;
    static Utils *sharedUtilsInstance = nil;

    dispatch_once( &onceToken, ^{
        sharedUtilsInstance = [ [Utils alloc] init];
    });

    return sharedUtilsInstance;
}
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
类定义,创建/销毁OC对象
类定义 1 OC类分为2个文件,一个是
C++全局对象的初始化和析构
众所周知,一个应用程序的开始是从main函数开始,到MAIN函数结束。 那么对于下面的程序 1.cpp class A { public:   A();  ~A(); } A g_a; int main() { return 0; } 2.cpp A g_a1; 全局对象g_a的初始化是谁去做的,以及他的析构又是有谁执行的。 答案是编译器。
类对象的成员变量初始化
#include<iostream> using namespace std; class Test { public: Test(int m=100):mb(m),ma(mb){} //ma=-858993460 mb=100 //类对象的成员变量初始化与成员在定义中的顺序有关 //与在初始化列表中的顺序无关 void Show() {
当类对象作为成员看初始化列表的意义
如果一个类中含对象成员。当创建这个类的对象时,C++编译器必须确保调用了所有子对象的构造函数。如果所有的子对象有默认构造,那么编译器会自动调用默认构造。如果子对象没有默认构造,亦或者想指定调用某个构造函数时,就必须用初始化列表。 class car { public: string name; car() { cout } car(string name) { this->
类初始化与类对象初始化
类的生命周期: 加载——> 验证、准备、解析——>初始化——>使用——>卸载 类初始化进行的5种情况: 1.遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的java代码场景是:使用new关键字实例化对象的时候、读取或者设置一个类的静态字段(被final修饰的除外),以及调用一
【C++】派生类对象初始化基类的引用
//派生类对象初始化基类的引用 //引用是别名,但这个别名只能包含派生类对象中的由基类继承来的隐藏对象 #include using namespace std; class B { public: B() { cout<<"B"<<endl; } void fun() { cout<<"B::fun()"<<endl; } private: int x; }; cla
c++类对象数组初始化的几种方法
<br />    类对象数组初始化<br />    如有一个如下类:<br />    class EquipmentPiece {<br />    private:<br />        int IDNumber;<br />    public:<br />        EquipmentPiece(int IDNumber) : IDNumber(IDNumber) {};<br />    };<br /> <br />    以下列出几种初始化的方法:<br />    <一>、对象数
类对象的初始化-构造函数
类对象的初始化方法: A、使用参数初始化表,对类中的成员变量进行初始化操作。 class Pen { public:         Pen(int size):m_size(size){}  //构造函数的声明,参数初始化表;         void Write(); private:     int m_size; }; B、默认参数构造函数 cla
C++之对象初始化详解
对象在创建时获得了一个特定的值,我们说这个对象被初始化。初始化不是赋值,初始化的含义是创建变量赋 予其一个初始值,而赋值的含义是把当前值擦除,而以一个新值来替代。 默认初始化:         如果定义变量时没有指定初值,则变量被默认初始化,此时变量被赋予了“默认值”         1、如果是内置类型的变量且未被显示初始化,它的值由位置决定。定义在任何函数体之外的变量被初始化
OC的类对象 与 类的加载方法和初始化方法
1.类也是个对象 类是一个对象是Class类型的对象简称类对象 Class类型的定义 // 一个任意的类型,表示一个Objective-C类 typedef struct objc_class *Class;  类名就代表着类对象,每个类只有一个类对象  获取类对象 // 获取类对象两种方式person1 和 person2     Class person1 =