访问实例变量的语法?(目标C)

Spa*_*yro 6 iphone objective-c ios ivar

在Objective-C中访问实例变量的正确语法是什么?

假设我们有这个变量:

@interface thisInterface : UIViewController {
    NSMutableString *aString;
}

@property (nonatomic, retain) NSMutableString *aString;
Run Code Online (Sandbox Code Playgroud)

它是合成的.

当我们想要访问它时,我们首先要分配并初始化它.我已经在Objective-C中编程了大约一个月,我看到了两种不同形式的语法.我见过人们做的很简单aString = [[NSMutableString alloc] initWithString:@"hi"],他们在那里分配字符串; 我也看到人们开始它self.aString然后他们继续初始化他们的伊娃.我想我只想弄清楚什么是初始化实例变量的最合适的方法,因为在前面的例子中,我收到了来自它的EXC_BAD_ACCESS错误.在预先设置之后self.,它没有出现.

如果这是一个重复的问题,请原谅我,但在阅读了SO上的一些帖子之后,这让我很好奇.我正在尝试用Objective-C学习正确的语法,因为我更喜欢正确而不是草率.

Ste*_*e N 13

如果您已@synthesize在.m文件中声明了属性,则只需将其设置为:

self.aString = @"hi"; // or [[NSMutableString alloc] initWithString:@"hi"];
Run Code Online (Sandbox Code Playgroud)

使用self.varName利用您的属性声明实际执行的操作 - 它处理新值的保留(因为您的属性具有retain属性),为您释放旧值等.

如果你这样做:

aString = someValue;
Run Code Online (Sandbox Code Playgroud)

...你可能正在泄漏原来的值aString,因为没有使用self.aString你直接访问变量vs通过属性.


oct*_*cty 9

需要注意的区别self->varNameself.varName

第一个是指针访问.第二是财产准入.

为什么这很重要?指针访问是直接的.另一方面,属性访问使用getter和setter(无论是否@synthesized).此外,为了方便起见,@synthesized访问器为您处理内存管理(即使用时self.varName = ...;),而varName = ...;只执行它所说的内容,即赋值 - >(这可能是您可能获得的EXC_BAD_ACCESS错误的解释).

从语法上讲,两种形式都是正确的.如果您想更好地传达意图,请self->varName在需要直接使用指针时使用self.varName,并在想要利用@property方便时使用.


nac*_*o4d 7

以下是所有可能的组合(我认为)OKs和BAD仅在aString属性具有retain属性时才正确:

@property (nonatomic, retain) NSMutableString *aString;
Run Code Online (Sandbox Code Playgroud)

所以:

1

aString = [[NSMutableString alloc] init]; //OK: 
Run Code Online (Sandbox Code Playgroud)

这是可以的,但只有在aString没有指向无效对象的情况下,否则您将丢失对该对象的引用,并且它将泄漏,因为您将无法访问它以释放它.

2

aString = [NSMutableString string]; //BAD
Run Code Online (Sandbox Code Playgroud)

不好,因为你想保留一个字符串(正如你所说的那样),你不会保留它,你将来肯定会得到EXC_BAD_ACCESS

3

aString = [[NSMutableString string] retain]; //OK
Run Code Online (Sandbox Code Playgroud)

与第一种方法相同,只有当aString没有指向有效对象时才有用.但是我会使用第一个.

4

aString = [[[NSMutableString alloc] init] autorelease];//BAD
Run Code Online (Sandbox Code Playgroud)

与第二种方法相同.

self.aString = [[NSMutableString alloc] init]; //BAD!!
Run Code Online (Sandbox Code Playgroud)

不好因为你保留了两次,因此会导致内存泄漏

6

self.aString = [[NSMutableString string]; //******GOOD!******
Run Code Online (Sandbox Code Playgroud)

这可能是最安全的.它将由属性设置器保留,因为您正在使用setter,所以可以由aString指向的任何其他对象将被适当地释放

7

self.aString = [[NSMutableString string] retain]; //BAD
Run Code Online (Sandbox Code Playgroud)

这保留了两次.

8

self.aString = [[[NSMutableString alloc] init] autorelease];//Ok
Run Code Online (Sandbox Code Playgroud)

这也没关系,但我会使用方便的方法代替这个漫长的方法:)

如果您知道自己在做什么,请注意#1和#3选项非常好.事实上,我比#6更频繁地使用它们