2

我不确定我应该如何初始化 Objective-C 类中的各种属性。请在您的回答中假设我是 Objective-C 的一个非常新的用户......

我有以下课程:

测试班

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

测试管理器类

@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
}

这将自动分配要存储在管理器类中的对象数组,因此我可以执行以下操作:

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

我什至不确定 initManager 是正确的使用方法 - 是否有内置的东西总是被调用?

4

3 回答 3

12

首先,让我们看看我们可以初始化您的 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
于 2013-07-08T21:01:29.760 回答
2

首先将测试和测试管理器类的头文件导入控制器类

#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];
}
于 2013-07-08T20:34:52.577 回答
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可能会使用 readonlyTestManager并借用上面使用的形式。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 中的所有初始化案例,但它只是一个开始。

于 2013-07-08T21:29:04.623 回答