Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于Objective-C属性语法的基本问题_Objective C_Cocoa_Cocoa Touch - Fatal编程技术网

关于Objective-C属性语法的基本问题

关于Objective-C属性语法的基本问题,objective-c,cocoa,cocoa-touch,Objective C,Cocoa,Cocoa Touch,关于目标C中属性的语法和用法,我有几个基本问题: 假设标题中有以下声明: @interface TestObject : NSObject { NSArray *myArray; } @property (nonatomic, retain) NSArray *myArray; 在实施过程中,我可以: 列表项 可交替使用myArray和self.myArray进行设置和获取 self.myArray=nil是否等同于[myArray发行版]? 如果是这样,是否有理由使用self.m

关于目标C中属性的语法和用法,我有几个基本问题:

假设标题中有以下声明:

@interface TestObject : NSObject {

    NSArray *myArray;
}

@property (nonatomic, retain) NSArray *myArray;
在实施过程中,我可以:

  • 列表项
  • 可交替使用
    myArray
    self.myArray
    进行设置和获取
  • self.myArray=nil
    是否等同于
    [myArray发行版]

    如果是这样,是否有理由使用
    self.myArray=nil
    而不是
    [myArray release]

  • 要设置setter/getter,您必须在main中实现它们:

    + (NSArray*) myArray {
    return myArray;
    }
    
    + (void) setMyArray:(NSArray*)input{
    myArray = input;
    }
    

    现有的两个答案都是错误的

    @合成生成如下所示的setter和getter:

    - (void)setMyArray:(NSArray*)array {
        if( myArray != array ) {
            [myArray release];
            myArray = [array retain];
        }
    }
    
    - (NSArray*)myArray {
        return myArray;
    }
    
    (请注意,它们与此不完全相同,如果指定“复制”或其他属性,它们也会有所不同,但这是基本公式)。现在我们可以看到
    self.myArray=nil将释放旧阵列。self.myArray和myArray在设置时不能互换。此外,
    self.myArray=nil将继续在垃圾收集的世界中工作

    正如Dave Delong指出的,self.myArray=nil将通知任何观察myArray的人更改的值,如果您在dealloc方法中这样做,这可能是一个问题。为了避免这种情况,您的dealloc将如下所示:

    - (void)dealloc {
        [myArray release]; myArray = nil;
        [super dealloc];
    }
    
    (注意
    myArray=nil;
    是这里的风格选择。)

  • myArray
    self.myArray
    实际上是不同的
    myArray
    直接访问变量,而
    self.myArray
    (相当于
    [self myArray]
    )调用访问器方法。大多数人都同意你应该一直使用
    self.myArray
    (或
    [self-myArray]
    ),而不要直接使用
    myArray
    。这是因为访问者可能有副作用;例如,如果直接设置变量,KVO将不起作用,内存管理也不会为您处理

  • 您的属性是用
    retain
    声明的,因此
    self.myArray=anArray
    (与
    [self-setMyArray:anArray]
    相同)执行以下操作:

  • 保留anArray,它将很快成为新的myArray
  • 释放旧的myArray,它很快将不再是myArray
  • 更改指针myArray,使其现在指向数组
  • 因此,当您执行self.myArray=nil
    时,其中一个步骤(#2)实际上是释放旧数组。(因为新的是
    nil
    ,我们不必担心它的内存管理,即使我们保留了它。)所以是的,
    self.myArray=nil
    是释放
    myArray
    的有效方法


    但是,如果您在
    dealloc
    中谈论释放
    myArray
    ,通常最好使用
    [myArray release]
    ,因为调用
    self.myArray=nil
    会产生副作用,如果任何其他对象通过KVO观察
    myArray
    。因此,虽然遵循内存管理标准,但使用
    self.myArray=nil
    编写
    dealloc
    方法并不是一个好主意。我知道我需要在实现中包含synthesis语句。-1 setter/getter方法是实例方法,不是类方法。这也是不正确的。您的方法(除了类方法而不是实例方法)正在执行简单的指针赋值,就好像属性被声明为
    assign
    。事实并非如此。它被声明为
    retain
    myArray
    属性,则code>可能会产生不良副作用。您不希望在对象解除分配时触发观察通知,因为这样,观察者可能会尝试访问部分解除分配的对象。这不是一个好主意。戴夫·德隆:正在解除分配的对象不应该有任何观察者。如果是这样的话,这本身就是程序中的一个bug。这是因为使用访问器可能会产生令人满意的副作用,包括(但不限于)KVO和内存管理。假设您已经在
    myArray
    中设置了
    retain
    -ed数组。然后设置
    myArray=newArray
    会泄漏旧的,而调用访问器(
    self.myArray=newArray
    )会释放旧的并保留新的。@JK可以随意使用
    self.myArray=nil除了你的
    dealloc
    方法之外的任何地方。要完全学究化;),步骤2.2仅当旧myArray与新myArray不同时才释放它。@JK从不自己调用DEALLOC(除非它是
    DEALLOC
    方法中的
    [super DEALLOC]
    )。这就是
    retain
    release
    的目的。而YVN22:我同意你不应该从
    dealoc
    向自己发送访问者消息,因为访问者方法本身可能有副作用,但如果你在对象点击
    dealoc
    时仍在观察对象的属性,那就是一个bug。