Цель C: Как написать персонализированный пользовательский Init

Очень простой вопрос, но в моем коде есть ошибка, на которую может ответить только одно предположение: мой класс не создается!

Я не много писал в Objective C за какое-то время, и я никогда не был действительно хорош, поэтому, пожалуйста, укажите даже самые болезненно очевидные.

Я использую:

ObjectSelectionViewController *length = [[ObjectSelectionViewController alloc] initWithMeasureType:0]; ObjectSelectionViewController *mass = [[ObjectSelectionViewController alloc] initWithMeasureType:1]; ObjectSelectionViewController *volume = [[ObjectSelectionViewController alloc] initWithMeasureType:2]; NSLog(@"%@", [length measurementType]); NSLog(@"%@", [mass measurementType]); NSLog(@"%@", [volume measurementType]); 

NSLogs возвращаются в зависимости от того, какое измерение было назначено последним, независимо от отдельных распределений и inits.

Вот конструктор класса ObjectSelectionViewController:

 #import "ObjectSelectionViewController.h" @implementation ObjectSelectionViewController NSString *measurementType; -(ObjectSelectionViewController*) initWithMeasureType:(int)value { switch (value) { case 0: // Length measureType = @"Length"; break; case 1: // Mass measureType = @"Mass"; break; case 2: // Volume measureType = @"Volume"; break; } return self; } -(NSString*) measurementType { return measureType; } 

Спасибо за помощь, это сводит меня с ума!

5 Solutions collect form web for “Цель C: Как написать персонализированный пользовательский Init”

Вам нужно сделать measureType переменной экземпляра, так что каждый объект этого типа, который вы создаете, имеет свою собственную копию:

 @interface ObjectSelectionViewController : NSViewController { NSString * measureType; // Declare an NSString instance variable } - (id) initWithMeasureType: (int)value; @end 

Как бы то ни было, существует только одна копия переменной, и каждый раз, когда вы создаете экземпляр нового объекта, его значение изменяется. Поскольку каждый экземпляр ссылается на одну и ту же копию, все они получают одинаковое значение:

 ObjectSelectionViewController *length = [[ObjectSelectionViewController alloc] initWithMeasureType:0]; NSLog(@"%@", [length measurementType]); // Prints "Length" ObjectSelectionViewController *mass = [[ObjectSelectionViewController alloc] initWithMeasureType:1]; NSLog(@"%@", [length measurementType]); // Prints "Mass" 

Вам также необходимо изменить свой метод init... как упомянуто другими респондентами:

 - (id) initWithMeasureType: (int)value { // Call superclass's initializer self = [super init]; if( !self ) return nil; switch (value) { case 0: // Length measureType = @"Length"; break; case 1: // Mass measureType = @"Mass"; break; case 2: // Volume measureType = @"Volume"; break; } return self; } 

Поскольку вы назначаете литеральную строку переменной экземпляра, вам не нужно беспокоиться об управлении своей памятью; если вы делаете что-то более сложное, вы, вероятно, добьетесь успеха, объявив свойство . Другое примечание: методы инициализатора всегда должны возвращать id , общий указатель объекта, чтобы позволить подклассам работать правильно.

Сначала нужно вызвать [super init] , например:

 -(id) initWithMeasureType:(int)value { if ((self = [super init])) { switch (value) { case 0: // Length measureType = @"Length"; break; case 1: // Mass measureType = @"Mass"; break; case 2: // Volume measureType = @"Volume"; break; } } return self; } 

Конструкторы – это соглашение в Objective-C, а не функция языка. Так, например, нет автоматического вызова родительских конструкторов (так же, как вы не ожидали бы, что какой-либо другой переопределенный метод вызовет его родительские реализации). Точно так же имена, используемые для конструкторов, являются просто условностями, поэтому компилятор ничего не знает об init . Имея это в виду, то, что вы действительно хотите в качестве своего конструктора:

 -(id) initWithMeasureType:(int)value { if((self = [super init])) { switch (value) { case 0: // Length measureType = @"Length"; break; case 1: // Mass measureType = @"Mass"; break; case 2: // Volume measureType = @"Volume"; break; } } return self; } 

Предполагая, что measureType – это переменная экземпляра (объявленная как часть интерфейса, вообще говоря), а не глобальная, тогда она должна делать то, что вы хотите.

В вашем обычном методе инициализации вам просто нужно начать с:

 self = [super init]; 
 - (id) initWithMeasureType: (int)value { // Call superclass's initializer self = [super init]; if( !self ) return nil; switch (value) { case 0: // Length measureType = @"Length"; break; case 1: // Mass measureType = @"Mass"; break; case 2: // Volume measureType = @"Volume"; break; } return self; 

}

  • Правильный способ инициализации UIView с помощью класса .xib и backing
  • Использование NSManagedObjectContextObjectsDidChangeNotification
  • Как установить из MFMailComposeViewController?
  • Метод dealloc не вызывается при установке объекта на nil
  • Блок анимации UIView: если продолжительность равна 0, то такая же, как без анимации?
  • Цель C & iOS: запуск таймера? NSTimer / Нитки / NSDate / и т.д.
  • Нажатие MFMailComposeViewController в стек навигации? Не представлено модально
  • CocoaLumberjack - как получить доступ к файлу журнала на устройстве?
  • Как воспроизвести видео с помощью MPMoviePlayerController
  • Как программно добавить UITabBarController и UINavigationController в AppDelegate?
  • UITableViewController - выпадающий список таблиц, чтобы показать новый UIView
  • Как получить случайный объект из экземпляра NSSet?
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.