简体   繁体   English

这两条线之间有什么区别?

[英]What's the difference between these two lines?

I'm using a GitHub repo named MNCalendar, and I wanted to call some cells. 我正在使用名为MNCalendar的GitHub repo,我想调用一些单元格。 Now, here's how I did it. 现在,我就是这样做的。

MNCalendarViewDayCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
MNCalendarViewDayCell *cell = (MNCalendarViewDayCell*)[self.collectionView cellForItemAtIndexPath:indexPath];

The first line gave me an issue about it being a MNCalendarViewDayCell pointer to UICollectionViewCell, but the other one was fine. 第一行给了我一个问题,它是一个指向UICollectionViewCell的MNCalendarViewDayCell指针,但另一个很好。 What's going on under the hood here, why is the bottom one correct? 引擎盖下发生了什么,为什么底部正确?

Not critical bug, just an issue, just wondering and trying to learn something from it :) 不是关键的错误,只是一个问题,只是想知道并试图从中学到一些东西:)

cellForItemAtIndexPath returns a pointer to a UICollectionViewCell object, but you're assigning the result to a MNCalendarViewDayCell . cellForItemAtIndexPath返回指向UICollectionViewCell对象的指针,但您将结果分配给MNCalendarViewDayCell

The warning is the compiler telling you "hey - this variable you've declared is a MNCalendarViewDayCell , but it looks like you're assigning an object of a different type to it'. 警告是编译器告诉你“嘿 - 你声明的这个变量是一个MNCalendarViewDayCell ,但看起来你正在为它分配一个不同类型的对象”。

In this case, this is intentional - you've created a custom sub-class of UICollectionViewCell . 在这种情况下,这是故意的 - 您已经创建了一个UICollectionViewCell的自定义子类。 This mis-matched type won't cause any problems. 这种不匹配的类型不会导致任何问题。 So to prevent the warning we do what's called casting : we tell the compiler even though the method says it will return a pointer to one class we expect it to be another: 因此,为了防止警告我们执行所谓的转换 :我们告诉编译器,即使该方法它将返回一个指向一个类的指针,我们希望它是另一个类:

MNCalendarViewDayCell *cell = (MNCalendarViewDayCell*)[self.collectionView cellForItemAtIndexPath:indexPath];

[self.collectionView cellForItemAtIndexPath:indexPath] returns UICollectionViewCell . [self.collectionView cellForItemAtIndexPath:indexPath]返回UICollectionViewCell Not all UICollectionViewCell objects are MNCalendarViewDayCell , that's why you get the warning. 并非所有UICollectionViewCell对象都是MNCalendarViewDayCell ,这就是您收到警告的原因。 By explicit cast (MNCalendarViewDayCell *) you tell compiler that it is MNCalendarViewDayCell . 通过显式转换(MNCalendarViewDayCell *)您告诉编译器它是MNCalendarViewDayCell

cellForItemAtIndexPath: returns a UICollectionViewCell instance. cellForItemAtIndexPath:返回一个UICollectionViewCell实例。 But you are assigning it to a MKCalendarViewCell variable. 但是您将它分配给MKCalendarViewCell变量。

If MKCalendarViewCell is a subclass of UICollectionViewCell, then there isn't really a problem under the Liskov Substitution Principle. 如果MKCalendarViewCell是UICollectionViewCell的子类,那么Liskov Substitution Principle下没有真正的问题。 And Objective-C is a dynamic language so this is supported. 而Objective-C是一种动态语言,所以这是支持的。

The error you are seeing comes from the compiler, telling you that you are assigning an object of one type to a variable of the other type. 您看到的错误来自编译器,告诉您正在将一种类型的对象分配给另一种类型的变量。 And by casting it you are saying that although the return type is of one class, you know better and that it is actually an instance of another class. 通过强制转换你会说尽管返回类型是一个类,但你知道的更好,它实际上是另一个类的实例。 This now becomes your problem to verify that this is actually the case. 这现在成为您的问题,以验证实际情况。

So the first one grabs a pointer to a UICollectionViewCell , which is what the base class of MNCalendarViewDayCell is. 所以,第一个抓住一个指向UICollectionViewCell ,这是基类的MNCalendarViewDayCell是。 However whilst it's a super class you can't just assign it to a subclass, so what the (MNCalendarViewDayCell *) does is to say that you're going to cast the pointer from it's base class UICollectionViewCell into the subclass instead. 然而,虽然它是一个超级类,你不能只将它分配给一个子类,所以(MNCalendarViewDayCell *)所做的就是说你要将指针从它的基类UICollectionViewCell转换为子类。 That's why the second one works, as you're converting it to the right type needed for assignment. 这就是为什么第二个工作正常,因为你将它转换为分配所需的正确类型。

cellForItemAtIndexPath returns you UICollectionViewCell , not your custom MNCalendarViewDayCell . cellForItemAtIndexPath返回UICollectionViewCell ,而不是您的自定义MNCalendarViewDayCell So when you assign result to MNCalendarViewDayCell *cell , it raises error (According to OOP, parent doesn't know about it's child, but child knows about his parent). 因此,当您将结果分配给MNCalendarViewDayCell *cell ,它会引发错误(根据OOP,父母不知道它的孩子,但是孩子知道他的父母)。 So you simply typecast it into your child cell. 因此,您只需将其类型化为您的子单元格。

In both statements your are downcasting a UICollectionViewCell to MNCalendarViewDayCell . 在这两个语句中,您都将UICollectionViewCell 向下转换MNCalendarViewDayCell Since MNCalendarViewDayCell is a subclass of UICollectionViewCell it may implement methods that are not implemented in UICollectionViewCell , this is why you get the warning. 由于MNCalendarViewDayCellMNCalendarViewDayCell的子类, UICollectionViewCell它可能实现UICollectionViewCell中未实现的UICollectionViewCell ,这就是您收到警告的原因。 Using (MNCalendarViewDayCell *) forces the cast and drops the warning. 使用(MNCalendarViewDayCell *)强制转换并删除警告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM