2013-09-23 4 views
3

Я использую репо GitHub с именем MNCalendar, и я хотел назвать некоторые ячейки. Теперь, вот как я это сделал.В чем разница между этими двумя строками?

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

Первая линия дала мне вопрос про то, что указатель MNCalendarViewDayCell на UICollectionViewCell, но другой был в порядке. Что здесь происходит под капотом, почему нижняя правильная?

Не критическая ошибка, просто вопрос, просто интересно и пытается узнать что-то от него :)

ответ

2

cellForItemAtIndexPath возвращает указатель на объект UICollectionViewCell, но вы назначаете результат MNCalendarViewDayCell.

Это предупреждение компилятор говорит вам: «Эй, - эта переменная вы объявили это MNCalendarViewDayCell, но, похоже, вы присваиваете объект другого типа к нему»

В этом случае. это преднамеренно - вы создали собственный подкласс класса UICollectionViewCell.Это неверно подобранный тип не вызовет никаких проблем. Поэтому, чтобы предотвратить предупреждение, мы делаем то, что называется литье: мы сообщаем компилятору, хотя метод говорит, он вернет указатель на один класс, мы ожидаем, что он будет другим:

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

Так первый один выхватывает указатель на UICollectionViewCell, что и базовый класс MNCalendarViewDayCell есть. Однако, хотя это суперкласс, вы не можете просто назначить его подклассу, поэтому то, что делает (MNCalendarViewDayCell *), это сказать, что вместо этого вы нарисуете указатель из его базового класса UICollectionViewCell в подкласс. Вот почему второй работает, поскольку вы преобразовываете его в нужный тип, необходимый для назначения.

1

[self.collectionView cellForItemAtIndexPath:indexPath] возвращение UICollectionViewCell. Не все UICollectionViewCell объектов - MNCalendarViewDayCell, поэтому вы получаете предупреждение. Явным литом (MNCalendarViewDayCell *) вы говорите компилятору, что это MNCalendarViewDayCell.

0

cellForItemAtIndexPath возвращает вас UICollectionViewCell, а не пользовательский MNCalendarViewDayCell. Поэтому, когда вы назначаете результат MNCalendarViewDayCell *cell, он вызывает ошибку (согласно OOP, родитель не знает о его дочернем элементе, но ребенок знает о своем родителе). Таким образом, вы просто вводите его в свою дочернюю ячейку.

0

В обоих отчетах есть downcasting a UICollectionViewCell до MNCalendarViewDayCell. Поскольку MNCalendarViewDayCell является подклассом UICollectionViewCell, он может реализовывать методы, которые не реализованы в UICollectionViewCell, поэтому вы получаете предупреждение. Использование (MNCalendarViewDayCell *) заставляет бросить и бросает предупреждение.

1

cellForItemAtIndexPath: возвращает экземпляр UICollectionViewCell. Но вы назначаете его переменной MKCalendarViewCell.

Если MKCalendarViewCell является подклассом UICollectionViewCell, то по Принципу замены Лискова это не проблема. Objective-C - динамический язык, поэтому он поддерживается.

Ошибка, которую вы видите, происходит от компилятора, сообщая вам, что вы назначаете объект одного типа переменной другого типа. И, произнося его, вы говорите, что, хотя тип возврата имеет один класс, вы знаете лучше и что это на самом деле экземпляр другого класса. Теперь это становится вашей проблемой, чтобы убедиться, что это действительно так.

Смежные вопросы