iphone - objective-c 的奇怪行为

标签 iphone objective-c ios ios5

实际上我来自 java 背景,我正在学习 objective-c 。我对 Objective-C 的奇怪行为感到非常困惑。“请阅读第 3 个问题,它很重要。”

问题是按顺序提供的,所以请按我和其他人都能理解的顺序给出答案。

问题一
我有两个派生自 NSObject 的类: AB :

@interface A : NSObject 
@end                               

@interface B : NSobject
-(void)display; // It displays "I am class B"
@end

现在如果我这样做:

A *a = [[B alloc]init]; // Show warning not error (it must be illegal)
[a display];            // prints "I am class B"

它调用了类 B 的显示方法。我认为它不应该发生,因为:

  1. A没有方法 display .通过多态性。

  2. 这可能是一种安全威胁,因为我正在创建任何类的引用并传递任何其他类的对象并通过它访问数据。

  3. 可能存在设计问题 Dog类实例获取 Printer 的对象上课,现在我调用print Dog 上的方法实例。

  4. 我引用了 NSArray并传递了 NSMutableArray 的对象现在我调用NSMutableArray此实例上的方法。

    [nsarr addObject:@:abc];//看起来很奇怪

问题二
如果我有 Foo协议(protocol),如果有任何类没有确认它。不应允许在协议(protocol)引用中获取该类的对象。

@protocol Foo
@required
-(void)abc;
@end    

如果我调用:

id<Foo> obj= [[B alloc]init]; // Shows warning ignore it for now as it must be illegal also
[obj display];                // It will call display method which should be illegal  
  1. 这不应该发生,因为B不符合协议(protocol)Fooobj正在服用 B对象和调用 B实例方法。我认为它非常糟糕,因为多态性和安全性

问题三
如果我的类有一个类方法返回该类的一个未自动释放的对象,则编译器会显示警告。如果我将该类(不符合协议(protocol))方法返回的对象传递给协议(protocol)的引用。 (它应该是一个错误)。

id<Foo> obj = [Abc aClassMethodReturnsObjectWhichNotAutoreleased]; //show warning

它显示了一个很好的警告。 Abc不符合协议(protocol)Foo

但是

id<Foo> obj = [NSArray arrayWithObjects:@"abc",@"def",nil]; // It does **not** show a warning as it will return autorelease object. NSArray doesn't conform protocol Foo

为什么上面的赋值给了NSArray类不显示警告,因为它在前面的示例中显示。

提前致谢。

编辑

*回答第三个问题:*由于 NSArray 返回允许传入“id obj”的 id 对象,但在“aClassMethodReturnsObjectWhichNotAutoreleased”的情况下,该方法返回“ABC *”指针,这就是编译器的原因在这种情况下发出警告。

最佳答案

问题一:

A *a = [[B alloc]init]; //Show warning not error (it must be illegal)
[a display];  //prints "I am class B"

在这里,您为名为 a 的变量使用静态类型 A。然后,您将另一种类型的对象 (B) 分配给该变量。

与 java 不同,Objective-C 不会强制静态类型要求,但是它会在编译时警告您,因为编译器检测到声明的类型之间存在差异类型和对象的实际类型。不过,它很乐意将 B 对象填充到您的变量中,因此 a 现在指向您创建的 B 对象。一旦程序编译并运行(在运行时),A *a 将被视为与 id a 相同。

Objective-C 的另一个特性是您可以随时向任何对象发送任何消息。这是 Objective-C 动态特性的一部分。显然,在某些情况下,向对象发送错误消息会导致坏事 (tm) 发生,因此您需要确保只发送适当的消息。有多种函数可以在运行时测试对象的类,甚至可以在发送消息之前测试它是否能够处理特定消息,以防止坏事。如果您使用的是静态类型(如本例所示),那么编译器会发出警告,告诉您您可能犯了错误,应该检查代码。

问题 2:

这实际上与问题 1 非常相似。编译器警告您,您正在为变量分配看似不正确的值,但是在运行时您可以向任何对象发送任何消息,因此它会起作用在实际对象上,而不是类型声明中的“预期”对象。

问题 3:

好问题。我原以为你也会在那里收到警告。也许其他人可以提供帮助。我的第一个想法是这是一个错误,应该这样报告,但可能有一个我不知道的原因....

关于iphone - objective-c 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13322974/

相关文章:

ios - 在不打开默认邮件应用程序的情况下发送电子邮件

ios - 自定义键盘中的自动布局与高度约束冲突

objective-c - 如何在GCDAsyncsocket中设置tcp_nodelay?

iphone - UIPinchGestureRecognizer 没有响应

ios - UITableView 背景 View nil 在 iOS 5 中不起作用

ios - 如何从 ios 中的应用程序文件夹中按日期对 uiimages 进行排序

iphone:如何以编程方式检测最后一个来电号码?

iphone - 将数据库直接加载到 CoreData

ios - 按钮动画无法在 swift 中正常工作

ios - 如何在 swift 中使用 segue 发送用户信息以查看 Controller ?