代码如下
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(copy,nonatomic) NSString *String;
@end
实现
@implementation AppDelegate
//-(NSString *)String{
// NSLog(@"get");
// return _String;
//}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSMutableString *temp = [[NSMutableString alloc] init];
[temp appendString :@"NSMutableString"];
self.String = temp;
if (self.String == temp) {
NSLog(@"NSMutableString self.String == temp1");
} else {
NSLog(@"NSMutableString self.String != temp1");
}
NSLog(self.String);
NSString *temp1 =[ [NSString alloc] initWithFormat: @"NSString"];
self.String =temp1;
if (self.String == temp1) {
NSLog(@"NSString的copy self.String == temp1");
} else {
NSLog(@"NSString的copy self.String != temp1");
}
NSLog(self.String);
return YES;
}
//重写String的set 和 get 的方法(完全实现copy的方法,重写的目的只是为了理解 self.String = temp的实现顺序)
@synthesize String = _String;
-(NSString *)String{
NSLog(@"get");
return _String;
}
-(void)setString:(NSString *)String {
_String = [String copy];
if (_String == String) {
NSLog(@"是否相等");
}
NSLog(@"set");
}
打印结果:
2014-09-22 00:32:57.880 slidemenu[7226:232042] set
2014-09-22 00:32:57.881 slidemenu[7226:232042] get
2014-09-22 00:32:57.881 slidemenu[7226:232042] NSMutableString self.String != temp1
2014-09-22 00:32:57.881 slidemenu[7226:232042] get
2014-09-22 00:32:57.881 slidemenu[7226:232042] NSMutableString
2014-09-22 00:32:57.882 slidemenu[7226:232042] 是否相等
2014-09-22 00:32:57.882 slidemenu[7226:232042] set
2014-09-22 00:32:57.882 slidemenu[7226:232042] get
2014-09-22 00:32:57.882 slidemenu[7226:232042] NSString的copy self.String == temp1
2014-09-22 00:32:57.882 slidemenu[7226:232042] get
2014-09-22 00:32:57.882 slidemenu[7226:232042] NSString
这说明什么?
copy的属性是有限制的;
1,对于NSString的copy方法,copy前后NSString的地址相同( 这里可以看做@"",可以看做保存在固定内存中),但是对于NSMutableString的对象,就是copy出来新的地址,地址不相同。
2,另外copy属性也只能对具有实现copy协议的类才可以使用,不具有copy的协议,也会直接赋值。 3,self.String按正常逻辑来说就是执行get的方法吧 ,天经地义嘛!but,如果self.String = temp;你会发现没有执行get方法,只是执行了set方法,诡异吧,但是相信代码吧,实际上oc不是像java一样直接把temp的地址指向了self.String,这也体现了oc的方法全部是消息机制,即时是"="也是发送消息,通知去执行setString:;
如果没有 实行 = 的赋值,只是self.String 这时才会这时才会执行get的方法!
行文逻辑有点乱,如果偶然被你看到,不要看我在说些什么,跑遍代码把,实践出真知!