Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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 区分iVar和方法参数?_Objective C - Fatal编程技术网

Objective c 区分iVar和方法参数?

Objective c 区分iVar和方法参数?,objective-c,Objective C,我有一个这样的财产: @property (nonatomic, strong) IBOutlet UIImageView *backgroundImageHolder; -(void)setBackgroundImageHolder:(UIImageView *)backgroundImageHolder { // .h @interface Foo : NSObject { IBOutlet UIImageView *myfooImageView; } @property (n

我有一个这样的财产:

@property (nonatomic, strong) IBOutlet UIImageView *backgroundImageHolder;
-(void)setBackgroundImageHolder:(UIImageView *)backgroundImageHolder {
// .h
@interface Foo : NSObject {
    IBOutlet UIImageView *myfooImageView;
}

@property (nonatomic, retain) UIImageView *publicFooImageView;

// .m
@implementation Foo
@synthesize publicFooImageView=myfooImageView;
@end
我想调整setter,XCode会像这样填写方法签名:

@property (nonatomic, strong) IBOutlet UIImageView *backgroundImageHolder;
-(void)setBackgroundImageHolder:(UIImageView *)backgroundImageHolder {
// .h
@interface Foo : NSObject {
    IBOutlet UIImageView *myfooImageView;
}

@property (nonatomic, retain) UIImageView *publicFooImageView;

// .m
@implementation Foo
@synthesize publicFooImageView=myfooImageView;
@end
但是,要在该方法中实际执行任何操作,我必须将参数
backgroundImageHolder
更改为类似
backgroundImageHolderIn
的内容。有没有办法避免这种情况?有没有办法在不重新调用setter(导致无休止的循环)或只是再次引用参数的情况下设置iVar

我刚才试过:

self->backgroundImageHolder = backgroundImageHolder;
但是编译器还是警告我


注意:我使用的是编译器为属性自动生成的iVar,但默认情况下其名称相同。

编译器警告您,因为当您声明
@property
时,它会创建与属性(以及setter方法的参数)名称完全相同的实例变量。避免这种情况的一种方法是创建不同名称的实例变量,然后使用
@synthesis
将其与属性配对,如下所示:

@property (nonatomic, strong) IBOutlet UIImageView *backgroundImageHolder;
-(void)setBackgroundImageHolder:(UIImageView *)backgroundImageHolder {
// .h
@interface Foo : NSObject {
    IBOutlet UIImageView *myfooImageView;
}

@property (nonatomic, retain) UIImageView *publicFooImageView;

// .m
@implementation Foo
@synthesize publicFooImageView=myfooImageView;
@end

您可以告诉编译器如何命名生成的ivar:

@synthesize propertyName = iVarName;
如果实际存在名为
iVarName
的ivar,则使用该ivar。如果它不存在,编译器会为您创建它

比如:


现在您可以访问实例变量
myBackgroundImageHolder
。您不需要首先在接口中声明它。

最清楚的做法是:

在标题中,为backgroundImageHolder定义一个iVar,如下所示

@interface Something : NSObject
{
  IBOutlet UIImageView *_backgroundImageHolder
}
注意前面的下划线

然后在.m文件中,按如下方式使用synthesis调用:

@synthesize backgroundImageHolder=_backgroundImageHolder;

或者自己定义getter和setter方法:这样就可以通过“_backgroundImageHolder”访问ivar,而不会有再次意外调用setter的危险

现在,冲突的参数名称似乎已经被很好地涵盖了。基本上,您必须:

  • 重命名传入参数
  • 重命名合成的iVar
一旦您有了一个不同于您试图设置的iVar的方法参数,您就拥有了编写自定义setter所需的一切。为了避免无限循环,无论是通过点语法还是方法括号语法,都不必调用当前实现的setter。相反,请直接参考支持iVar。您需要注意手动实现在属性中声明的内存管理语义(assign vs.retain,等等):


我自己也很想知道,我经常想检查自定义访问器中ivar的前一个值是多少。请注意,您不需要在头中的接口中声明ivar。我通常不会,因为它实际上是一个实现细节,不涉及类的消费者。。。谢谢我已经知道了这个选项,问题是它的代码太多,没有什么好处。必须为属性声明冗余IVAR是非常可怕的。正确。有时我喜欢明确声明它们的可读性,但这不是必要的。我应该在问题中提到,我已经知道这种可能性。至少你没有明确声明iVar,这是不相关的。如果我没有更好的解决方案,至少我可以有一个全面的答案。很好,谢谢!另外,应该说,“假设赋值语义或弧”,我的例子用
strong
@Yar:是的,我错过了
strong
。在这种情况下,您不必担心,因为IVAR是使用适当的所有权限定符合成的。