code1使用“_”进行分配:
$user=User::where(['id'=>Auth::user()->id])->with('questions','answers','comments','comments.votes','votes')
->first();
code1输出:
@interface ViewController ()
@property (nonatomic,retain) NSMutableString *rrstr;
@property (nonatomic,copy) NSMutableString *copystr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *ssss = [[NSMutableString alloc]initWithString:@"ddddd"];
_rrstr = ssss;
_copystr = ssss;
NSLog(@"%@===%@===%@",ssss,self.rrstr,self.copystr);
[ssss appendString:@"1231"];
NSLog(@"%@===%@===%@",ssss,self.rrstr,self.copystr);
[ssss deleteCharactersInRange:NSMakeRange(1, 3)];
NSLog(@"%@===%@===%@",ssss,self.rrstr,self.copystr);
}
code2使用“。”做任务:
2016-09-19 10:44:29.190 retin[1160:72426] ddddd===ddddd===ddddd
2016-09-19 10:44:29.191 retin[1160:72426] ddddd1231===ddddd1231===ddddd1231
2016-09-19 10:44:29.192 retin[1160:72426] dd1231===dd1231===dd1231
code2输出:
@interface ViewController ()
@property (nonatomic,retain) NSMutableString *rrstr;
@property (nonatomic,copy) NSMutableString *copystr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableString *ssss = [[NSMutableString alloc]initWithString:@"ddddd"];
self.rrstr = ssss;
self.copystr = ssss;
NSLog(@"%@===%@===%@",ssss,self.rrstr,self.copystr);
[ssss appendString:@"1231"];
NSLog(@"%@===%@===%@",ssss,self.rrstr,self.copystr);
[ssss deleteCharactersInRange:NSMakeRange(1, 3)];
NSLog(@"%@===%@===%@",ssss,self.rrstr,self.copystr);
}
我很困惑为什么这两个代码有不同的输出?这些代码不应该具有相同的输出吗? “_”和“。”之间的区别究竟是什么。语法?
答案 0 :(得分:2)
当您在Objective-C中声明@property
时,编译器会为您做一些事情。
_propertyName
,但您可以使用@synthesize
指令getter
和setter
个函数。默认情况下,这些只需设置并获取支持实例变量,但您可以再次覆盖这些函数并提供自己的setter和getter实现。许多人错误地认为_propertyName
只是进入房产的“捷径”,但事实并非如此。它直接访问后备变量,绕过setter和getter函数。
在许多情况下它并不重要,但在某些情况下确实如此,其中一个就是你发现的copy
属性。
copy
是属性的属性,而不是基础变量,因此当您声明
@property (nonatomic,copy) NSMutableString *copystr;
Objective-C创建以下getter和setter函数,如下所示:
-(NSMutableString *) copyStr {
return _copyStr;
}
-(void) setCopyStr: (NSMutableString *)value {
_copyStr = [value copy];
}
所以,现在你可以看到说
之间的区别_copyStr = ssss; // This is a straight pointer assignment
和
self.copyStr = ssss; // This is actually a call to [self setCopyStr:ssss]
在第一种情况下,不调用setter,因此永远不会复制; _copyStr
是对ssss
字符串的引用,因此当您更改ssss
时,该更改会反映在_copyStr
中,因为它们引用了同一个对象。
在第二种情况下,调用setter并复制ssss
,并将对新副本的引用分配给_copyStr
;现在,当ssss
更改时,_copyStr
引用的副本不受影响。
简而言之,除非您有特定理由绕过setter / getter,否则总是使用self.propertyName
。