如何在Objective C中初始化NSMutableArray?

Xi *_*ang 11 objective-c nsmutablearray

我来自Java背景,我正在学习Objective C.我正在尝试创建一个具有字符串数组和成员函数来修改数组的类.我的代码看起来像这样:

@implementation TAWChapter

@synthesize mSubject;

@synthesize mItems;

- (id) init{
    self.mItems = [[NSMutableArray alloc] init];
    return self; 
}

- (void) setSubject:(NSString *)subject{
    self.mSubject = subject; 
}

- (void) addItem:(NSString *)item{
    [self.mItems addObject:@"asdf"]; 
}

@end
Run Code Online (Sandbox Code Playgroud)

哪个没用.我得到了一个"[__NSArrayI addObject:]: unrecognized selector sent to instance "和一个"NSInvalidArgumentException".在互联网上搜索后,我将构造函数中的单行更改为:

self.mItems = [self.mItems init];
Run Code Online (Sandbox Code Playgroud)

它有效,但为什么呢?从Java开发人员的角度来看,第一个比第二个更有意义.我有另一条线,它与第一条线相同,但它正在工作(不在构造函数中).有人可以向我解释一下吗?

dre*_*lax 28

  1. 首先,您应该遵守Objective-C编码约定.在Objective-C中,类没有构造函数,它们具有初始化程序.在Objective-C中,初始化程序调用超类的初始化程序,因此它应如下所示:

    - init
    {
        self = [super init];
        if (!self) return nil;
    
        // set up other stuff here 
    
        return self;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 其次,除非您使用ARC,否则可能会发生内存泄漏.初始化程序的第一行将您拥有的对象分配给也可能拥有所有权的属性.你应该使用:

    // property takes care of ownership
    self.mItems = [NSMutableArray array];
    
    Run Code Online (Sandbox Code Playgroud)

    要么:

    // assign to instance variable directly with owned object
    mItems = [[NSMutableArray alloc] init];
    
    Run Code Online (Sandbox Code Playgroud)

    Apple有时不鼓励在初始化程序中使用访问器方法,因为它可以摆弄KVO之类的东西,但是一致使用访问器方法可确保正确的对象所有权和内存管理.

  3. 通过将初始化中的行更改为:

    self.mItems = [self.mItems init];
    
    Run Code Online (Sandbox Code Playgroud)

    什么.调用初始化方法时(通常在分配之后),所有实例变量都自动设置为nil.所以你所做的只是:

    self.mItems = [nil init];
    
    Run Code Online (Sandbox Code Playgroud)

    这只是:

    self.mItems = nil;
    
    Run Code Online (Sandbox Code Playgroud)

    并且,如果init没有先分配实例,请不要使用,并且永远不要使用init多次.

  4. 如果你不让超类初始化,那么它可能表现为其他领域的问题.进行构建和分析,确保您已解决分析仪指出的任何问题.


MJB*_*MJB 6

由于objective-c是c的超集,它基本上是带有一些"OO"语法糖的c.在创建(或使用!)对象之前,必须在堆中为它分配空间.你这样做[Class alloc].下一步是初始化该空间.alloc返回一个指向堆中该空间的指针,用init初始化;)

所以你打电话Class *myObjc = [[Class alloc] init];.

如果你使用继承(你从NSOBject继承,那么你必须使用继承),你必须确保你的超类正确地初始化了所有内容,即调用super.为了确保没有出现运行时错误,请检查self!= nil,这是隐式使用if(self)

self.mItems = [self.mItems init]; // doesn't do anything, since you call the getter for mItems with self.mItems and try to init. then you try to set mItmes to itself. 
Run Code Online (Sandbox Code Playgroud)

使用此代码:

@implementation TAWChapter

@synthesize mSubject, mItems;

- (id)init
{
    self = [super init];
    if (self) {
        mItems = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void) setSubject:(NSString *)subject{
    mSubject = subject; 
}

- (void) addItem:(NSString *)item{
    [mItems addObject:item]; 
}

@end
Run Code Online (Sandbox Code Playgroud)