如何在Objective-C中初始化对象

时间:2013-07-08 20:29:40

标签: objective-c memory-management allocation

我不确定如何初始化Objective-C类中的各种属性。请假设我在你的答案中是Objective-C的新用户......

我有以下课程:

测试课

@interface Test : NSObject
@property (nonatomic, strong) NSString *name;
@end

TestManager类

@interface TestManager : NSObject
@property (nonatomic, strong) NSMutableArray *tests; // array of Test objects (array size unknown until runtime)
@end

控制器类

@interface TestController : NSObject
@property (nonatomic, strong) TestManager *aManager;
-(void)initManager;
-(void)doSomething;
@end

我想要一个名为initManager的方法:

-(void)initManager
{
    // how can I init the aManager which will have an array of Test objects
}

将自动分配要存储在manager类中的对象数组,以便我可以执行以下操作:

-(void)doSomething
{
   NSString *name = ((Test *)[self.aManager.tests objectAtIndex:0]).name;
}

我甚至不确定initManager是否是正确使用的方法 - 内置的内容总是被调用吗?

3 个答案:

答案 0 :(得分:7)

首先,让我们看一下初始化Test类对象的方式。

您也可以为Test类编写一些初始化方法,而不是:

Test example = [[Test alloc] init];
example.name = @"s";

你可以这样写:

Test example = [[Test alloc] initWithName:@"s"];

请注意,这对于初始化方法返回新创建的对象非常常见,因此初始化方法通常返回'id'类型(不是void)。

这是您的测试类的实现,将在下面的示例中使用。

.h文件:

- (id)initWithName:(NSString *)aName;

.m文件:

- (id)initWithName:(NSString *)aName 
{
   self = [super init];
   if (self) {
     _name = aName;
   }
  return self;
}

您可以这样初始化TestController类:

.h文件:

- (id)initManager;

.m文件:

- (id)initManager
{
  self = [super init]; //always call the superclass init method when your class inherit from other class
  if (self) { // checking if the superclass initialization was fine
    _tests = [NSMutableArray array];
    [_tests addObject:[[Test alloc] initWithName:@"s"]]; 
    [_tests addObject:[[Test alloc] initWithName:@"l"]];
  }
  return self;
}

或类似的东西:

- (id)initManager
{
  self = [super init]; //always call the superclass init method when your class inherit from other class
  if (self) { // checking if the superclass initialization was fine
    _tests = [NSArray arrayWithObjects:[[Test alloc] initWithName:@"s"], [[Test alloc] initWithName:@"l"]];
  }
  return self;
}

就像@Andrew说的那样,最好使用alloc + init。以下是此语法的一些示例:

CGRect rect = CGRectMake(0, 0, 100, 100);
[[UIView alloc] initWithFrame:rect];

[[NSArray alloc] init]

这是初始化对象的常用方法。尽管有这种机制,但还有一些额外的方法(实际上是静态函数),它们为程序员提供了初始化对象的好方法。使用它们你不必编写关键字'alloc',这样代码就更短,更容易阅读。

[NSArray array] //creates and returns empty array
[NSMutableArray array] //creates and return empty mutable array

[UIButton buttonWithType:UIButtonTypeContactAdd]; //creates and return button

答案 1 :(得分:2)

首先将test和test manager类的头文件导入控制器类

#import Test.h
#import TestManager.h

然后在控制器类

-(void)initManager
{
    TestManager *aTestManager = [TestManager new];

    Test *test1 = [Test new];
    Test *test2 = [Test new];

    [aTestManager.tests addObject:test1];
    [aTestManager.tests addObject:test2];
}

答案 2 :(得分:1)

让我们从顶部开始吧。您可能并且应该将名称readonly

(演示假设ARC已启用)

@interface Test : NSObject
@property (nonatomic, readonly) NSString *name;

// and then simply initialize name:
- (instancetype)initWithName:(NSString *)pName;

@end
应复制

NSString个属性:

@implementation Test

- (instancetype)initWithName:(NSString *)pName
{
 self = [super init];
 if (nil == self) return nil;
 // copy the NSString:
 // don't use getters/setters in initializers or -dealloc
 _name = pName.copy;
 return self;
}

@end

同样readonly

@interface TestManager : NSObject
@property (nonatomic, strong, readonly) NSMutableArray *tests; // array of Test objects (array size unknown until runtime)
@end

@implementation TestManager

- (id)init
{
 self = [super init];
 if (nil == self) return nil;
 // just initialize readonly tests:
 _tests = NSMutableArray.new;
 return self;
}

@end

然后TestController可能会使用只读TestManager并借用上面使用的表单。否则,如果需要,它可以是readwrite

// don't declare/implement an instance method
// which has the prefix -init*, like initManager. renamed.
 - (void)resetManager
 {
  // if readonly is ok, then just create it in the initializer.
  // otherwise, if you need the ability to set the manager in the controller,
  // then declare the property readwrite and:
  self.testManager = TestManager.new;
  // note: aManager is not a good name. renamed to testManager.
 }

- (void)doSomething
{
 assert(self.testManager && "did you forget to init the manager?");
 Test * test = [self.testManager.tests objectAtIndex:0];
 NSString * name = test.name;
 ...
}

这远不是涵盖ObjC中的所有初始化案例,但它是一个开始。