我来自
Java背景,我正在学习Objective C.我正在尝试创建一个具有字符串数组和成员函数来修改Array的类.我的代码看起来像这样:
@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
哪个没有工作.我得到一个“_ _NSArrayI addObject:]:不可识别的选择器发送到实例”和一个“NSInvalidArgumentException”.在互联网上搜索后,我将构造函数中的单行更改为:
self.mItems = [self.mItems init];
它工作,但为什么?从Java开发者的角度来看,第一个比第二个更有意义.而且我有另一行与第一行相同,但它是有效的(不是在构造函数中).有人可以向我解释一下吗
解决方法
>首先,你应该遵守Objective-C编码惯例.在Objective-C中,类没有构造函数,它们具有初始化器.在Objective-C中,初始化器调用超类的初始化器,因此应该如下所示:
- init { self = [super init]; if (!self) return nil; // set up other stuff here return self; }
>其次,除非您使用ARC,否则可能会有内存泄漏.您的初始化器的第一行将您拥有的对象分配给可能拥有所有权的属性.你应该使用:
// property takes care of ownership self.mItems = [NSMutableArray array];
要么:
// assign to instance variable directly with owned object mItems = [[NSMutableArray alloc] init];
苹果有时会阻止在初始化器中使用访问器方法,因为它可以使KVO等操作变得简单,但是一致地使用访问器方法可确保正确的对象所有权和内存管理.
>将您的初始化器中的行更改为:
self.mItems = [self.mItems init];
什么也没做.当您的初始化方法被调用时(通常在分配之后),所有实例变量都将自动设置为nil.所以你在做什么只是:
self.mItems = [nil init];
这只是:
self.mItems = nil;
并且,不要在没有先分配一个实例的情况下使用init,而不要使用init多次.>如果你不让超类自己初始化,那么它可能会在其他领域出现问题.做一个建筑&分析并确保您已经解决了分析仪指出的任何问题.