27

快速提问...好吧,我知道在 Objective-C 中所有属性都以 nil 开头,并且向 nil 发送消息什么都不做,因此您必须使用 [[Class alloc] init]; 进行初始化。在向新创建的属性发送消息之前。但是,如果我没有向该属性发送消息,或者我使用 self.property = something 设置属性怎么办?在这些情况下我是否也需要分配 init ?此外,UI 属性是否也以 nil 开头,例如从情节提要中拖出的 UILabel 属性?这些需要alloc init吗?

感谢所有回答的人

4

4 回答 4

40

Stunner 很好地解释了不需要分配已经创建的 init 对象。

但如果它是一个不存在的对象,你将在哪里创建它?我提到的一个非常常见的模式是延迟实例化,因为您在帖子中提到了它。

所以你想要一个 NSMutableArray 属性。您可以在使用它之前在某些方法中分配初始化它,但是您必须担心“在我需要我的数组之前是否调用了该方法?” 或“我是否会不小心再次调用它并重新初始化它。”

所以一个故障安全的地方是在属性的吸气剂中。每次访问该属性时都会调用它。

.h
@property (nonatomic, strong) NSMutableArray* myArray;

.m
@synthesize myArray = _myArray;

- (NSMutableArray*)myArray
{
    if (!_myArray) {
        _myArray = [[NSMutableArray alloc] initWithCapacity:2];
    }
    return _myArray;
}

每次访问该属性时,它都会显示“myArray 是否存在?如果不存在,请创建它。如果存在,则返回我所拥有的。”

此外,这种设计模式的另一个好处是,在您需要资源之前,您不会创建资源,而不是在视图控制器加载或应用程序启动时一次性创建它们,这取决于需求,可能需要几个秒。

于 2012-08-02T02:34:47.320 回答
4

现实情况是,当您这样做时self.myProperty = [[Class alloc] init],您并没有初始化您的属性。相反,你正在初始化一个你告诉你的属性(实际上是一个指针)指向的对象。因此,如果您已经有一个已分配和初始化的对象,您不必再次分配/初始化,您可以这样做self.myProperty = object

UI 属性不会以 nil 开始,这是因为当您在界面构建器中添加元素时,视图拥有您添加的元素,并且这些对象会自动为您初始化。这意味着如果您正在创建 IBOutlets 并将它们连接到某些属性,则不必分配/初始化。

我希望这可以帮到你。

于 2012-08-02T00:52:36.670 回答
1

我没有使用 Storyboard 的经验,但我知道当您通过 xib 文件创建对象时,当您告诉视图控制器使用 xib 文件时,所有对象都会正确实例化。因此,您不必担心在代码中分配/初始化这些对象。

关于使用self.property = <something>,这取决于是什么something。如果某物是任何类型的现有对象,则无需对该对象执行 alloc init,因为self.property = ...语法会调用属性的 setter 方法,该方法将适当地保留、复制、分配等新值给属性。

现在任何类型的现有对象都可以是分配/初始化的对象,或者是从便利方法获得的自动释放对象(例如 NSString 的 stringWithFormat:)。

正如 Kaan Dedeoglu 指出的那样,self.property = ...语法将 ivar 指向(并保留)内存中的对象,如果该对象尚未实例化,则由您来初始化该对象。

于 2012-08-02T01:01:08.587 回答
0

不,您不需要 [[Class alloc]init 初始化方法中的属性。

但是,为了清楚起见,我鼓励您在 init 方法中将它们显式设置为 Nil。

于 2012-08-02T00:53:09.793 回答