Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.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 - Fatal编程技术网

“和”之间有区别吗;实例变量";及;不动产;在Objective-c中?

“和”之间有区别吗;实例变量";及;不动产;在Objective-c中?,objective-c,Objective C,Objective-c中的“实例变量”和“属性”之间有区别吗 我对此不是很确定。我认为“属性”是一个具有访问器方法的实例变量,但我可能认为是错误的。属性是一个更抽象的概念。实例变量实际上只是一个存储插槽,就像结构中的插槽一样。通常,其他对象永远不会直接访问它们。另一方面,属性是可以访问的对象的属性(听起来很模糊,应该是这样的)。通常,属性将返回或设置一个实例变量,但它可以使用多个实例变量中的数据,也可以根本不使用。例如: @interface Person : NSObject { NS

Objective-c中的“实例变量”和“属性”之间有区别吗


我对此不是很确定。我认为“属性”是一个具有访问器方法的实例变量,但我可能认为是错误的。

属性是一个更抽象的概念。实例变量实际上只是一个存储插槽,就像结构中的插槽一样。通常,其他对象永远不会直接访问它们。另一方面,属性是可以访问的对象的属性(听起来很模糊,应该是这样的)。通常,属性将返回或设置一个实例变量,但它可以使用多个实例变量中的数据,也可以根本不使用。例如:

@interface Person : NSObject {
    NSString *name;
}

    @property(copy) NSString *name;
    @property(copy) NSString *firstName;
    @property(copy) NSString *lastName;
@end

@implementation Person
    @synthesize name;

    - (NSString *)firstName {
        [[name componentsSeparatedByString:@" "] objectAtIndex:0];
    }
    - (NSString *)lastName {
        [[name componentsSeparatedByString:@" "] lastObject];
    }
    - (NSString *)setFirstName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
    - (NSString *)setLastName:(NSString *)newName {
        NSArray *nameArray = [name componentsSeparatedByString:@" "];
        NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
        self.name = [newNameArray componentsJoinedByString:@" "];
    }
@end

(注意:上面的代码是错误的,因为它假设名称已经存在,并且至少有两个组件(例如“比尔·盖茨”而不仅仅是“盖茨”)。我觉得修正这些假设会使代码的实际意义变得不那么清楚,所以我在这里指出它,这样就没有人会天真地重复这些错误。)

属性是实现某个值的getter/setter的一种友好方式,具有其他有用的特性和语法。属性可以由实例变量支持,但也可以定义getter/setter来执行更动态的操作,例如,可以在字符串上定义小写属性,动态创建结果,而不是返回某个成员变量的值

下面是一个例子:

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;
@property
行定义了类型为
NSString*
的名为
propertyName
的属性。可以使用以下语法获取/设置:

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
当您分配或读取
myObject.propertyName
时,实际上是在调用对象上的setter/getter方法

@synthesis
行告诉编译器为您生成这些getter/setter,使用与属性同名的成员变量来存储值(或者
otherVarName
,如果您在注释中使用语法)

除了
@synthesis
之外,您仍然可以通过定义自己的getter/setter来覆盖其中一个getter/setter。这些方法的命名约定是setter的
setPropertyName:
,getter的
propertyName
(或
getPropertyName
,非标准)。另一个仍将为您生成

@property
行中,您可以在属性的参数中定义一些属性,这些属性可以自动执行线程安全和内存管理等操作。默认情况下,属性是原子的,这意味着编译器将使用适当的锁包装
@synthez
ed get/set调用,以防止并发问题。您可以指定
非原子
属性来禁用此功能(例如,在iPhone上,您希望将大多数属性默认为
非原子

有3个属性值控制任何
@合成的
设置器的内存管理。第一个是
retain
,它将自动将
release
发送到属性的旧值,并将
retain
发送到新值。这是非常有用的

第二个是
copy
,它将复制传入的任何值,而不是保留它们。对NSString使用
copy
是一种很好的做法,因为调用者可以传入一个NSMutableString,然后从您的下方将其更改出来<代码>复制
将对只有您有权访问的输入进行新的复制

第三个是
assign
,它在不调用旧对象或新对象上的retain/release的情况下执行直接指针赋值


最后,您还可以使用
readonly
属性来禁用属性的setter。

我对接口部分使用属性,其中对象与其他对象接口
实例变量是您在类中需要的东西-除了您之外没有人应该看到和操作它们。

默认情况下,readwrite属性将由实例变量支持,实例变量将再次由编译器自动合成

实例变量是存在的变量,在对象的生命周期内保持其值。用于实例变量的内存在首次创建对象时分配(通过alloc),并在解除分配对象时释放


除非另行指定,否则合成的实例变量与属性具有相同的名称,但带有下划线前缀。例如,对于名为firstName的属性,合成的实例变量将被称为_firstName。

以前,人们公开使用属性,而IVAR用于私人用途,但几年前,您还可以在
@implementation
中定义属性以私下使用它们。但如果可能的话,我仍然会使用IVAR,因为要输入的字母更少,而且根据需要它运行得更快。这是有意义的,因为属性意味着“重”:它们应该从生成的getter/setter或手动编写的getter/setter访问


然而,在苹果最近的代码中,IVAR不再使用。我猜是因为它更像是
objc
而不是
C/C++
,而且它更容易使用
assign
nullable
等属性。

Objective-C属性与实例变量(iVar)

实例变量

@interface SomeClass: NSObject
NSString *someVariable;
@end
财产

@interface SomeClass: NSObject
@property (nonatomic, strong) NSString *someVariable;
@end
属性
在内部使用
实例变量
<代码>属性=变量+有界getter/setter
。它是一个具有可变语法和访问权限的方法调用

  • @property
    生成
    getter
    setter
    方法(访问器方法),该方法使用
    支持ivar
    (也称为支持字段),您可以通过下划线
    使用这些方法(
    \u一些变量

  • 由于它调用方法-
    方法调度
    机制被使用
    #import "SomeClass.h"
    
    @interface SomeClass()
    @property (nonatomic, strong) NSString *someVariable;
    @end
    
    @implementation SomeClass
    
    - (void) foo {
    
        //property getter method
        NSString *a1 = self.someVariable; //NSString *a1 = [self someVariable];
    
        //property setter method
        self.someVariable = @"set someVariable"; //[self setSomeVariable:@"set someVariable"];
    
        //iVar read
        NSString *a2 = _someVariable;
        //iVar write
        _someVariable = @"set iVar";
    
    }
    
    //if you overriding someVariable getter and setter the iVar(_someVariable) is not generated, that is why you can:
    
    //1. create some variable explicitly
    NSString *_someVariable;
    
    //or
    
    //2. use @synthesize 
    @synthesize someVariable = _someVariable;
    
    //overriding
    - (NSString*) someVariable {
        return _someVariable;
    }
    
    - (void)setSomeVariable: (NSString*) updatedSomeVariable {
        _someVariable = updatedSomeVariable;
    }
    
    @end