Что такое лучшие практики, которые Вы используете при записи Objective C и Какао? [закрытый]

346
задан 7 revs, 6 users 50% 23 November 2011 в 02:55
поделиться

29 ответов

Существует несколько вещей, я начал делать это, я не думаю, являются стандартными:

1) С появлением свойств, я больше не использую "_" для добавления префикса "частных" переменных класса. В конце концов, если к переменной могут получить доступ другие классы, не должно там быть свойство для него? Мне всегда не нравилось "_" префикс для того, чтобы сделать код более ужасным, и теперь я могу пропустить его.

2) Разговор о частных вещах, я предпочитаю помещать определения закрытого метода в.m файле в расширении класса как так:

#import "MyClass.h"

@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end

@implementation MyClass

, Почему загромождают.h файл с вещами, о которых не должны заботиться посторонние? Пустое () работы для частных категорий в.m файле и проблемы компилируют предупреждения, если Вы не реализуете объявленные методы.

3) я взял к помещению dealloc наверху.m файла, чуть ниже @synthesize директив. Не был должен, о чем Вы dealloc быть наверху списка вещей Вы хотите думать в классе? Это особенно верно в среде как iPhone.

3.5) В ячейках таблицы, сделайте каждый элемент (включая саму ячейку) непрозрачным для производительности. Это означает выбирать соответствующий цвет фона во всем.

3.6) При использовании NSURLConnection как правило, можно хотеть реализовать метод делегата:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
      return nil;
}

я нахожу, что большинство веб-вызовов очень исключительно, и это - больше исключение, чем правило, Вы будете желать кэшируемые ответы, специально для вызовов веб-сервиса. Реализация метода как показано отключает кэширование ответов.

Также интереса, некоторый хороший iPhone определенные подсказки от Joseph Mattiello (полученный в списке рассылки iPhone). Существуют больше, но они были самыми вообще полезными, я думал (обратите внимание, что несколько битов были теперь немного отредактированы из оригинала для включения деталей, предлагаемых в ответы):

4) Только двойная точность использования, если Вы имеете к, такой, работая с CoreLocation. Удостоверьтесь, что Вы заканчиваете свои константы в 'f', чтобы заставить gcc сохранить их как плавания.

float val = someFloat * 2.2f;

Это главным образом важно, когда someFloat может на самом деле быть двойное, Вам не нужна математика смешанного режима, так как Вы теряете точность в 'val' на устройстве хранения данных. В то время как числа с плавающей запятой поддерживаются в аппаратных средствах на iPhone, может все еще потребоваться больше времени, чтобы сделать арифметику с двойной точностью в противоположность одинарной точности. Ссылки:

По более старым телефонам, предположительно, вычисления работают на той же скорости, но у Вас может быть больше компонентов одинарной точности в регистрах, чем удваивается, таким образом, для многих вычислений одинарная точность закончит тем, что была быстрее.

5) Набор Ваши свойства как nonatomic. Они atomic по умолчанию и после синтеза, семафорный код будет создан для предотвращения проблем многопоточности. 99% из Вас, вероятно, не должны волноваться об этом, и код намного менее чрезмерно увеличен в размере и более эффективен памятью, когда установлено на неатомарный.

6) SQLite может быть очень, очень быстрый способ кэшировать большие наборы данных. Приложение карты, например, может кэшировать свои мозаики в файлы SQLite. Самая дорогая часть является дисковым вводом-выводом. Избегайте многих маленьких записей путем отправки BEGIN; и COMMIT; между большими блоками. Мы используем 2 вторых таймера, например, которые сбрасывают на каждом новом, отправляют. Когда это истекает, мы отправляем ФИКСАЦИЮ; который заставляет все Ваши записи входить в один большой блок. SQLite хранит данные транзакции к диску, и выполнение этого Начинают/Заканчивают переноситься, избегает создания многих файлов транзакций, группируя все транзакции в один файл.

кроме того, SQL заблокирует Ваш GUI, если это будет на Вашем основном потоке. Если у Вас есть очень длинный запрос, Это - хорошая идея сохранить Ваши запросы как статические объекты и выполнить Ваш SQL на отдельном потоке. Удостоверьтесь, что обернули что-либо, что изменяет базу данных для строк запроса в @synchronize() {} блоки. Поскольку короткие запросы просто оставляют вещи на основном потоке для более легкого удобства.

[еще 1129] подсказки по оптимизации SQLite здесь, хотя документ кажется устаревшим, многие точки, вероятно, все еще хороши;

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

399
ответ дан 14 revs, 9 users 67% 23 November 2019 в 00:30
поделиться

Я знаю, что пропустил это при первом вхождении в программирование Какао.

Удостоверяются, что Вы понимаете обязанности по управлению памятью относительно файлов NIB. Вы ответственны за выпуск объектов верхнего уровня в любом файле NIB, который Вы загружаете. Читайте Документация Apple на предмете.

10
ответ дан mj1531 23 November 2019 в 00:30
поделиться

Не забывайте, что NSWindowController и NSViewController выпустят объекты верхнего уровня файлов NIB, которыми они управляют.

при ручной загрузке файла NIB Вы ответственны за выпуск, что объекты верхнего уровня NIB, когда Вы сделаны с ними.

13
ответ дан mj1531 23 November 2019 в 00:30
поделиться

Кроме того, полусвязанная тема (с комнатой для большего количества ответов!):

, Что является теми небольшими подсказками XCode & приемы, которых Вы желаете Вам, знали приблизительно 2 года назад? .

15
ответ дан 2 revs 23 November 2019 в 00:30
поделиться

Все эти комментарии являются замечательными, но я действительно удивлен, что никто не упомянул Руководство по стилю Objective C Google , который был опубликован некоторое время назад. Я думаю, что они сделали очень полное задание.

17
ответ дан slf 23 November 2019 в 00:30
поделиться

Вымойтесь в dealloc.

Это - одна из самых легких вещей забыть - особенно при кодировании на уровне 150 миль в час. Всегда, всегда, всегда очищайте свои переменные атрибутов/участника в dealloc.

мне нравится использовать атрибуты Objc 2 - с новая запись через точку - таким образом, это делает очистку безболезненной. Часто столь же простой как:

- (void)dealloc
{
    self.someAttribute = NULL;
    [super dealloc];
}

Это будет заботиться о выпуске для Вас и устанавливать атрибут в NULL (который я рассматриваю безопасным программированием - в случае, если другой метод далее вниз в dealloc доступах, членская переменная снова - редкий, но могла , происходит).

С GC, включенным в 10,5, это не необходимо так больше - но Вы, возможно, все еще должны были бы очистить ресурсы других, которые Вы создаете, можно выполнить в этом завершить метод вместо этого.

21
ответ дан 2 revs, 2 users 93% 23 November 2019 в 00:30
поделиться

При использовании Leopard (Mac OS X 10.5) или позже можно использовать Инструментальное приложение, чтобы найти и отследить утечки памяти. После создания Вашей программы в XCode выберите Выполнение>, Запускаются с Инструмента Производительности> Утечки.

, Даже если Ваше приложение не показывает утечек, можно иметь в наличии объекты слишком долго. В Инструментах можно использовать инструмент ObjectAlloc для этого. Выберите инструмент ObjectAlloc в своем Инструментальном документе и поднимите деталь инструмента (если это уже не показывает) путем выбора View> Detail (это должно иметь галочку рядом с ним). Под "Продолжительностью жизни Выделения" в деталях ObjectAlloc, удостоверьтесь, что Вы выбираете переключатель рядом с "Созданным & Все еще жить".

Теперь каждый раз, когда Вы прекращаете записывать свое приложение, выбирая инструмент ObjectAlloc, покажет Вам сколько ссылок, там к каждому все еще живущему объекту в Вашем приложении в "# Сетевой" столбец. Удостоверьтесь, что Вы не только смотрите на свои собственные классы, но также и классы Ваших объектов верхнего уровня файлов NIB. Например, если у Вас нет окон на экране, и Вы видите ссылки на все еще живущий NSWindow, Вы не могли выпустить его в своем коде.

22
ответ дан mj1531 23 November 2019 в 00:30
поделиться

Думайте о нулевых значениях

Как этот вопрос примечания, сообщения к nil действительны в Objective C. Пока это часто - преимущество - ведущий к более чистому и более естественному коду - функция может иногда приводить к специфическим и difficult-to-track-down ошибкам, если Вы добираетесь nil значение, когда Вы не ожидали его.

26
ответ дан 2 revs 23 November 2019 в 00:30
поделиться

Сопротивляйтесь разделению на подклассы мира. В Какао много сделано через делегацию и использование базового времени выполнения, которое в других платформах сделано посредством разделения на подклассы.

, Например, в Java Вы используете экземпляры анонимных *Listener подклассы много, и в.NET Вы используете Ваш EventArgs подклассы много. В Какао Вы не делаете ни одного, какой — целевое действие используется вместо этого.

37
ответ дан Chris Hanson 23 November 2019 в 00:30
поделиться

Не используйте неизвестные строки в качестве строк формата

, Когда методы или функции берут аргумент строки формата, необходимо удостовериться, что Вы управляете содержанием строки формата.

, Например, при входе строк, заманчиво передать строковую переменную как единственный аргумент NSLog:

    NSString *aString = // get a string from somewhere;
    NSLog(aString);

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

    NSLog(@"%@", aString);
110
ответ дан 2 revs, 2 users 97% 23 November 2019 в 00:30
поделиться

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

Примеры того, что сделать и что не сделать:

  • не объявляют id m_something; в интерфейсе объекта и называют его членская переменная или поле ; используйте something или _something для его имени и назовите его переменная экземпляра .
  • не называют метода get -getSomething; надлежащее имя Какао всего -something.
  • не называют метод set -something:; это должно быть -setSomething:
  • , имя метода вкраплено аргументами и включает двоеточия; это -[NSObject performSelector:withObject:], не NSObject::performSelector.
  • межограничения Использования (Camel-регистр) в именах методов, параметрах, переменных, именах классов, и т.д. а не underbars (подчеркивания).
  • Имена классов запускаются с прописной буквы, имен переменной и имен методов с нижним регистром.

Независимо от того, что Вы делаете, , не делают использование Win16/Win32-style Венгерская запись. Даже Microsoft разочаровалась в этом с перемещением на платформу.NET.

108
ответ дан 2 revs, 2 users 96% 23 November 2019 в 00:30
поделиться

IBOutlets

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

@interface MyClass :NSObject {
    NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end

Используя свойства ясно дает понять семантику управления памятью; это также обеспечивает последовательный шаблон при использовании синтеза переменной экземпляра.

107
ответ дан 2 revs 23 November 2019 в 00:30
поделиться

Используйте Статический Анализатор LLVM/Clang

ПРИМЕЧАНИЕ: Под Xcode 4 это теперь встроено в IDE.

Вы используете Лязг, Статический Анализатор к - неудивительно - анализирует Ваш C и код Objective C (никакой C++ все же) на Mac OS X 10.5. Это тривиально, чтобы установить и использовать:

  1. Загрузка последняя версия от эта страница .
  2. От командной строки, cd к Вашему каталогу проекта.
  3. Выполняются scan-build -k -V xcodebuild.

(Существуют некоторые дополнительные ограничения и т.д., в особенности необходимо проанализировать проект в его конфигурации "Отладки" - видят http://clang.llvm.org/StaticAnalysisUsage.html для деталей - но это более или менее, к чему он сводится.)

анализатор тогда производит ряд веб-страниц для Вас, который показывает вероятное управление памятью и другие основные проблемы, что компилятор неспособен обнаружить.

98
ответ дан 2 revs, 2 users 91% 23 November 2019 в 00:30
поделиться

Это - тонкое, но удобное. При передаче себя как делегат в другом объекте сбросьте делегата того объекта перед Вами dealloc.

- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}

Путем выполнения этого Вы удостоверяетесь, что больше методов делегата не будет отправлено. Поскольку Вы собираетесь dealloc и исчезаете в эфире, Вы хотите удостовериться, что ничто не может отправить, Вы больше обмениваетесь сообщениями случайно. Помните, что self.someObject мог быть сохранен другим объектом (это мог быть одиночный элемент или на пуле автовыпуска или безотносительно), и пока Вы не говорите, что это "прекращает отправлять мне сообщения!", это думает, что Ваш объект just-about-to-be-dealloced является справедливой игрой.

Вхождение в эту привычку сохранит Вас от большого количества странных катастрофических отказов, которые являются болью для отладки.

тот же принципал относится к Наблюдению Значения ключа и NSNotifications также.

Редактирование:

Еще больше обороны, изменение:

self.someObject.delegate = NULL;

в:

if (self.someObject.delegate == self)
    self.someObject.delegate = NULL;
95
ответ дан 3 revs, 3 users 94% 23 November 2019 в 00:30
поделиться

Заявленные Свойства

необходимо обычно использовать функцию Objective-C 2.0 Declared Properties для всех свойств. Если они не общедоступны, добавьте их в расширении класса. Используя заявленные свойства заставляет семантику управления памятью сразу очиститься и облегчает для Вас проверять Ваш dealloc метод - если Вы группируете свои объявления свойства вместе, можно быстро просканировать их и соответствовать реализации dealloc метода.

необходимо думать трудно перед не маркировкой свойств как 'неатомарные'. Как Руководство Языка программирования Objective C примечания, свойства являются атомарными по умолчанию и подвергаются значительным издержкам. Кроме того, просто создание всех Ваших атомарных свойств не подает Вашу ориентированную на многопотоковое исполнение заявку. Также обратите внимание, конечно, что, если Вы не определяете 'неатомарный' и реализуете свои собственные методы доступа (вместо того, чтобы синтезировать их), необходимо реализовать их атомарным способом.

31
ответ дан 3 revs, 2 users 92% 23 November 2019 в 00:30
поделиться

@kendell

Вместо:

@interface MyClass (private)
- (void) someMethod
- (void) someOtherMethod
@end

Использование:

@interface MyClass ()
- (void) someMethod
- (void) someOtherMethod
@end

Новый в Objective C 2.0.

расширения Класса описаны в Objective C Apple 2.0 Ссылки.

"Расширения класса позволяют Вам объявлять дополнительный необходимый API для класса в местоположениях кроме в основном классе @interface блок"

, Таким образом, они - часть фактического класса - и НЕ (частная) категория в дополнение к классу. Тонкое но важное различие.

87
ответ дан 3 revs, 2 users 97% 23 November 2019 в 00:30
поделиться

Избегайте, чтобы автовыпуск

Начиная с Вас обычно (1) не имел прямого контроля за их время жизни, автовыпущенные объекты могут сохраниться в течение сравнительно долгого времени и излишне увеличить объем потребляемой памяти Вашего приложения. Пока на рабочем столе это может не иметь большого значения, на более ограниченных платформах это может быть значительной проблемой. На всех платформах, поэтому, и особенно на более ограниченных платформах, это считают лучшей практикой для избегания использования методов, которые привели бы к автовыпущенным объектам, и вместо этого Вы поощряетесь использовать alloc/init шаблон.

Таким образом, а не:

aVariable = [AClass convenienceMethod];

, где способный, необходимо вместо этого использовать:

aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];

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

Таким образом, вместо:

- (MyClass *)convenienceMethod {
    MyClass *instance = [[[self alloc] init] autorelease];
    // configure instance
    return instance;
}

Вы могли записать:

- (MyClass *)newInstance {
    MyClass *instance = [[self alloc] init];
    // configure instance
    return instance;
}

, Так как имя метода начинается "новый", потребители Вашего API знают, что они ответственны за выпуск полученного объекта (см., например, NSObjectController newObject метод ).

(1) можно взять на себя управление при помощи собственных локальных объединений автовыпуска. Для больше на этом, см. Пулы Автовыпуска .

75
ответ дан 2 revs, 2 users 99% 23 November 2019 в 00:30
поделиться

Запишите модульные тесты. Можно протестировать партия из вещей в Какао, которое могло бы быть более твердо в других платформах. Например, с кодом UI, можно обычно проверять, что вещи соединены, поскольку они должны быть и положить, что будут работать, когда используется. И можно установить работоспособное состояние & вызовите методы делегата легко для тестирования их.

у Вас также нет общественности по сравнению с защищенным по сравнению с видимостью закрытого метода мешающей записи тестов для Ваших внутренностей.

56
ответ дан Chris Hanson 23 November 2019 в 00:30
поделиться

Золотое правило: Если Вы alloc тогда Вы release!

ОБНОВЛЕНИЕ: Если Вы не используете ARC

55
ответ дан 2 revs, 2 users 60% 23 November 2019 в 00:30
поделиться

Не пишите Objective C, как будто это был Java/C#/C ++/etc.

я однажды видел команду, привыкшую к записи, что веб-приложения EE Java пытаются записать настольное приложение Какао. Как будто это было веб-приложение EE Java. Было много AbstractFooFactory и FooFactory и IFoo и Foo, суетящегося, когда все, в чем они действительно нуждались, было классом Foo и возможно протоколом Fooable.

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

55
ответ дан 3 revs, 3 users 80% 23 November 2019 в 00:30
поделиться

Удостоверьтесь, что Вы отмечаете страница Debugging Magic . Это должно быть Вашей первой остановкой при стуке по голове о стену при попытке найти источник ошибки Какао.

, Например, это скажет Вам, как найти метод, где Вы сначала выделили память, которая позже вызывает катастрофические отказы (как во время завершения приложения).

50
ответ дан mj1531 23 November 2019 в 00:30
поделиться

Строки вида как пользователь хотят

при сортировке строк для представления пользователю, Вы не должны использовать простое compare: метод. Вместо этого необходимо всегда использовать локализованные методы сравнения такой в качестве localizedCompare: или localizedCaseInsensitiveCompare:.

для получения дополнительной информации, см. Искать, Сравнение и Сортировка Строк .

38
ответ дан mmalc 23 November 2019 в 00:30
поделиться

Старайтесь избегать того, что я теперь решил назвать Newbiecategoryaholism. Когда вновь прибывшие к Objective C обнаруживают категории, они часто переходят пожиратель ресурсов дикие, добавляющие полезные небольшие категории к каждому существующему классу (, "Что? я могу добавить метод для преобразования числа в римские цифры к скале NSNumber на!" ).

не делают этого.

Ваш код будет более портативным и легче понять с десятками небольших методов категории, опрыснутых сверх двух дюжин фундаментальных классов.

Большую часть времени, когда Вы действительно думаете, что Вам нужен метод категории, чтобы помочь оптимизировать некоторый код, который Вы найдете, Вы никогда не заканчиваете тем, что снова использовали метод.

также существуют другие опасности, если Вы не пространство имен Ваши методы категории (и кто помимо совершенно безумного ddribin?) существует шанс, что Apple или плагин, или что-то еще работающее в Вашем адресном пространстве также определит тот же метод категории с тем же именем с немного отличающимся побочным эффектом....

хорошо. Теперь, когда Вас предупредили, проигнорируйте, "не вносят свой вклад". Но осуществите экстремальную сдержанность.

38
ответ дан 2 revs, 2 users 95% 23 November 2019 в 00:30
поделиться

Некоторые из них были уже упомянуты, но вот то, о чем я могу думать первое, что пришло на ум:

  • Следуют за KVO называющие правила. , Даже если Вы не используете KVO теперь, по моему опыту, часто времена, это все еще выгодно в будущем. И если Вы используете KVO или привязку, необходимо знать, что дела идут, прокладывают себе путь, они, как предполагается. Это покрывает не только методы доступа и переменные экземпляра, но и к - много отношений, проверки, автоуведомляя зависимые ключи, и так далее.
  • Помещенные закрытые методы в категории. Не только интерфейс, но и реализация также. Хорошо иметь некоторое расстояние концептуально между частными и незакрытыми методами. Я включаю все в свой.m файл.
  • Помещенные методы фонового потока в категории. То же как выше. Я нашел, что хорошо сохранить ясный концептуальный барьер, когда Вы думаете о том, что находится на основном потоке и что не.
  • Использование #pragma mark [section]. Обычно я группируюсь своими собственными методами, переопределениями каждого подкласса, и любой информацией или формальными протоколами. Это делает намного легче перейти к точно, что я ищу. По той же теме, похожие методы группы (как методы делегата табличного представления) вместе, не просто засуньте их где угодно.
  • закрытые методы Префикса & ivars с _. мне нравится способ, которым это смотрит, и я, менее вероятно, буду использовать ivar, когда я буду иметь в виду свойство случайно.
  • не используют мутаторные методы / свойства в init & dealloc. у меня ничего никогда не было, плохо происходят из-за него, но я вижу логику, если Вы изменяете метод, чтобы сделать что-то, что зависит от состояния Вашего объекта.
  • Помещенный IBOutlets в свойствах. я на самом деле просто считал этого здесь, но я собираюсь начать делать его. Независимо от любых преимуществ памяти это кажется лучше стилистически (по крайней мере, мне).
  • Стараются не писать код, в котором Вы не абсолютно нуждаетесь. Это действительно покрывает много вещей, как создание ivars, когда #define сделает, или кэширование массива вместо того, чтобы сортировать его каждый раз, когда данные необходимы. Существует много, я мог сказать об этом, но нижняя строка, не пишут код, пока Вам не нужен он, или профилировщик говорит Вам. Это делает вещи намного легче поддержать в конечном счете.
  • Конец, что Вы запускаете. Наличие большого количества наполовину законченного, содержащего ошибки кода является самым быстрым способом уничтожить погибшего проекта. Если Вам нужен тупиковый метод, это прекрасно, просто укажите на него путем помещения NSLog( @"stub" ) внутренняя часть, или однако Вы хотите отслеживать вещи.
70
ответ дан Marc Charbonneau 23 November 2019 в 00:30
поделиться

Use NSAssert and friends. I use nil as valid object all the time ... especially sending messages to nil is perfectly valid in Obj-C. However if I really want to make sure about the state of a variable, I use NSAssert and NSParameterAssert, which helps to track down problems easily.

26
ответ дан 23 November 2019 в 00:30
поделиться

Включите все предупреждения GCC, затем отключите те, которые регулярно появляются из-за заголовков Apple, чтобы уменьшить шум.

Также часто запускайте статический анализ Clang; вы можете включить его для всех сборок с помощью параметра сборки «Запуск статического анализатора».

Напишите модульные тесты и запускайте их с каждой сборкой.

10
ответ дан 23 November 2019 в 00:30
поделиться

Один довольно очевидный вариант для новичка: используйте функцию автоматического отступа Xcode для своего кода. Даже если вы копируете / вставляете из другого источника, после того, как вы вставили код, вы можете выбрать весь блок кода, щелкнуть его правой кнопкой мыши и затем выбрать вариант повторного отступа всего в этом блоке.

Xcode фактически проанализирует этот раздел и сделает в нем отступ на основе скобок, циклов и т. Д. Это намного эффективнее, чем нажатие клавиши пробела или табуляции для каждой строки.

12
ответ дан 23 November 2019 в 00:30
поделиться

Простой, но часто забываемый. Согласно спецификации:

Вообще, методы в разных классы, которые имеют один и тот же селектор (одно и то же имя) также должны совместно использовать одинаковые типы возврата и аргумента. Этот ограничение накладывается компилятором разрешить динамическую привязку.

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

@interface FooInt:NSObject{}
-(int) print;
@end

@implementation FooInt
-(int) print{
    return 5;
}
@end

@interface FooFloat:NSObject{}
-(float) print;
@end

@implementation FooFloat
-(float) print{
    return 3.3;
}
@end

int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    
    id f1=[[FooFloat alloc]init];
    //prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar
    NSLog(@"%f",[f1 print]);

    FooFloat* f2=[[FooFloat alloc]init];
    //prints 3.3 expectedly as the static type is FooFloat
    NSLog(@"%f",[f2 print]);

    [f1 release];
    [f2 release]
    [pool drain];

    return 0;
}   
23
ответ дан 23 November 2019 в 00:30
поделиться

Представленные Apple образцы, которые я видел, рассматривали делегат приложения как глобальное хранилище данных, своего рода диспетчер данных. Это заблуждение. Создайте синглтон и, возможно, создайте его экземпляр в делегате приложения, но не используйте делегат приложения как нечто большее, чем обработка событий на уровне приложения. Я искренне поддерживаю рекомендации в этой записи в блоге . Эта цепочка сообщила мне.

8
ответ дан 23 November 2019 в 00:30
поделиться