一些模糊的知识点

1、问题一

NSString * s1 = @"hello";

NSString *s2 = s1; s1 = @"world";

NSLog(@"s2 is %@", s2); 为啥不是 输出world 原因是什么?

原因在于字符串`NSString`在Objective-C中的赋值行为。当你执行下面的代码时:

```objc
NSString *s1 = @"hello";
NSString *s2 = s1;
```

这里,`s1`初始化为字符串`@"hello"`的一个引用,而后`s2`被赋予了和`s1`相同的引用,这意味着此时`s1`和`s2`都指向内存中同一个`@"hello"`字符串对象。

然而,当你更新`s1`的引用指向`@"world"`时:

```objc
s1 = @"world";
```

这个操作改变了`s1`的引用,使之指向一个新的字符串对象`@"world"`。但这个改变仅限于`s1`。因为在Objective-C中,变量赋值是按引用赋值(对于对象而言),所以`s2`的指向并没有改变,它仍然指向最初`@"hello"`字符串对象的位置。对象本身并没有被修改(实际上字符串对象在Objective-C中是不可变的),而只是变量`s1`的引用被改变指向了另一个对象。

因此,当你打印`s2`的值时:

```objc
NSLog(@"s2 is %@", s2);
```

控制台输出“s2 is hello”,这是因为`s2`依然指向它最初被赋予的字符串`@"hello"`的内存地址,而`@"world"`只是后来被赋给`s1`的另一个独立的字符串对象。

这种行为展示了如何字符串(以及其他对象)在Objective-C中是通过引用来管理和传递的,以及变量指针如何独立于所指向的对象本身变化。

如果是 C++中的引用,是不是就会输出 world?

如果你在C++中使用引用来模拟类似的行为,结果会不同。请注意,Objective-C中的指针和C++中的引用是两种不同的概念。在C++中,引用本质上是原始变量的别名,不能重新绑定到另一个变量。这是和Objective-C中指针(可以重新指向其他对象)的主要区别。

看下面的C++代码:

```cpp
std::string s1 = "hello";
std::string& s2 = s1; // s2 是 s1 的引用,不能重新绑定
s1 = "world"; // 修改 s1 也就是同时修改了 s2,因为 s2 是 s1 的别名
std::cout << "s2 is " << s2 << std::endl; // 输出 "s2 is world"
```

在上面的C++代码示例中,`s2`是对`s1`的引用。当`s1`的值变为`"world"`时,`s2`作为`s1`的引用,也随之看到了同样的变化,因此输出将会是`"s2 is world"`。

这里需要强调的是,C++中的引用在初始化后就与其对应的变量成为了别名,并且无法重新绑定到另一个变量。这种行为与Objective-C中的指针不同,在Objective-C中指针可以重新指向不同的对象。
2、问题二

Preson *p = [[Preson alloc] init];

p.xname = @"1111"; Preson *p2 = p;

p.xname = @"2222";

NSLog(@"p2 name is %@", p2.xname);

为什么输出2222

首先,请确认类名“Preson”是否是您意图中的“Person”,这里假设是一个拼写错误,我们将其理解为“Person”。

在您提供的Objective-C代码中,您创建了一个名为`p`的`Person`对象,并且将其属性`xname`设置为`@"1111"`。接着,您创建了`p2`,它是对`p`的引用。

```objc
Person *p = [[Person alloc] init];
p.xname = @"1111";
Person *p2 = p;
```

在Objective-C中,变量`p`和`p2`都是指向同一个`Person`对象的指针。这意味着任何对`p`所引用的对象的修改都会反映到`p2`上,因为它们都指向同一个内存地址。

之后,您更改了`p`所引用的`Person`对象的`xname`属性为`@"2222"`。

```objc
p.xname = @"2222";
```

这个改变直接影响了`Person`对象本身的状态,由于`p`和`p2`指向的是同一个对象,所以当您尝试打印`p2.xname`时,您会看到最新的属性值`@"2222"`。

```objc
NSLog(@"p2 name is %@", p2.xname);  // 输出 "p2 name is 2222"
```

控制台输出“p2 name is 2222”,这是因为`p2`和`p`是同一个对象的引用,它们共享对象的状态,包括所有属性的最新值。所以,一旦`xname`的值被更改,通过任一指针(`p`或`p2`)访问都会得到相同的结果。


 

UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; showView.backgroundColor = [UIColor redColor]; 
UIView *showView2 = [[UIView alloc] initWithFrame:CGRectMake(100, 230, 150, 150)]; 
showView2.backgroundColor = [UIColor yellowColor]; [self.view addSubview:showView]; [self.view addSubview:showView2]; 
[showView2 addSubview:showView]; 
为什么 showView 不是同时出现在self.view 和 showView2 上?

在 iOS 开发中,一个 `UIView` 实例只能有一个父视图(superview)。当你将一个视图添加到另一个视图时,它会从以前的父视图中移除并添加到新的父视图中。因此,`showView` 不能同时出现在 `self.view` 和 `showView2` 中。

在你提供的代码中,首先将 `showView` 添加到 `self.view`:

```objc
[self.view addSubview:showView];
```

然后又将 `showView` 添加到 `showView2`:

```objc
[showView2 addSubview:showView];
```

第二个操作会将 `showView` 从 `self.view` 中移除,并将其添加到 `showView2` 中。结果是 `showView` 仅出现在 `showView2` 中,而不再在 `self.view` 中。

如果你希望 `showView` 和 `showView2` 都出现在 `self.view` 中,但 `showView` 在视觉上似乎是 `showView2` 的子视图,你可以调整它们的 frame,使得 `showView` 看起来像是在 `showView2` 内部。例如:

```objc
UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(100, 230, 100, 100)];
showView.backgroundColor = [UIColor redColor];

UIView *showView2 = [[UIView alloc] initWithFrame:CGRectMake(100, 230, 150, 150)];
showView2.backgroundColor = [UIColor yellowColor];

[self.view addSubview:showView2];
[self.view addSubview:showView];
```

这里,`showView` 和 `showView2` 都被直接添加到 `self.view` 中,并且通过调整 `showView` 的 frame 使其看起来像是 `showView2` 的子视图。如果你需要 `showView` 实际上是 `showView2` 的子视图,那么你必须确保 `showView` 只被添加到 `showView2`,而不是同时添加到 `self.view`。

总之,一个 `UIView` 不能同时在两个父视图中存在。你需要根据具体的需求来设计视图层次结构。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值