Установите для свойства ScrollBars
значение DataGridView
на None
и используйте этот код для установки размера строк:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.Height = (dataGridView1.ClientRectangle.Height - dataGridView1.ColumnHeadersHeight) / dataGridView1.Rows.Count;
}
Также используйте этот код для обработки изменения размера:
private void dataGridView1_SizeChanged(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.Height = (dataGridView1.ClientRectangle.Height - dataGridView1.ColumnHeadersHeight) / dataGridView1.Rows.Count;
}
}
Новички часто ставят под сомнение эту тему:
По сути, это проистекает из идеи, что суперкласс мог переопределить назначенный инициализатор, чтобы вернуть отличается от объекта, возвращенного из + alloc
. Если вы не назначили возвращаемое значение инициализатора super
в self
, то вы потенциально могли иметь дело с частично инициализированным объектом (потому что объект, который super
инициализированный не тот объект, который вы инициализируете).
В целом, это '
Все остальные пункты здесь верны, но для вас также важно понимать, что self
является неявным параметром для каждого метода Objective-C (objc_msgSend()
передает его) и может быть записан, как любой другой параметр метода. (Запись в явные параметры, как правило, не одобряется, если только они не являются параметрами.)
Как правило, это делается только в методе -init
по причинам, указанным другими. Это имеет какой-то эффект только потому, что self
возвращается из метода и используется в присваивании id obj = [[NSObject alloc] init];
. Это также влияет на неявное разрешение иваров, потому что, например, если myVar является иваром моего класса, то доступ к нему осуществляется через метод вызывает его неявное разрешение в self->myVar
.
Если [super init]
возвращает nil, это означает, что вы были освобождены, и ваш параметр self
теперь является недействительным указателем. Слепо следуя соглашению self = [super init]
, вы избавите себя от потенциально неприятных ошибок.
Рассмотрим следующий нестандартный инициализатор:
- (id)initWithParam:(id)param {
if (!param) {
// Bad param. Abort
self = [super init]; // What if [super init] returns nil?
[self release];
return nil;
}
else
{
// initialize with param.
...
}
}
Что теперь произойдет, если мой суперкласс решит прервать и вернуть nil? Я был удален, и мой параметр self
теперь недействителен, и [self release]
вылетит. Переназначая self
, я избегаю этого сбоя.
Это правда, что init может вернуть nil
, если инициализация не удалась. Но это не основная причина, по которой вы должны назначать self при реализации своих собственных инициализаторов.
Об этом упоминалось ранее, но необходимо подчеркнуть еще сильнее: экземпляр, возвращенный из инициализатора, может быть не тем же экземпляром как и тот, который вы отправили, на самом деле он может даже не относиться к тому же классу!
Некоторые классы используют это как стандарт, например, все инициализаторы для NSString
и NSArray
всегда будет возвращать новый экземпляр другого класса. Инициализаторы для UIColor
часто возвращают другой экземпляр специализированного класса.
И вы сами можете реализовать что-то вроде этого, если хотите:
Я все еще новичок в Objective C, но этот пост помог мне понять это.
Подводя итог, большинство вызовов init возвращают тот же объект, что self уже инициализирован. Если есть ошибка, то init вернет nil. Кроме того, некоторые объекты, такие как синглтоны или уникальные объекты (например, NSNumber 0), будут возвращать объект, отличный от инициализированного (синглтон или глобальный объект 0). В этих ситуациях вам нужно иметь ссылку на сам объект. Я ни в коем случае не являюсь экспертом в том, что происходит здесь за кулисами, но для меня это имеет смысл на поверхности.
В Objective-C инициализаторы имеют возможность возвращать nil в случае сбоя или возвращать объект, совершенно отличный от того, для которого инициализатор был вызван (например, NSArray всегда делает это). Если вы не зафиксируете возвращаемое значение init
, метод может выполняться в контексте освобожденного объекта.
Некоторые люди не согласны с тем, следует ли вам выполнять назначение всего объекта. -self ригамароль, если вы не ожидаете, что получит что-то еще от инициализатора суперкласса, но это обычно считается хорошим защитным кодированием.
И да, это выглядит странно.