Скройте переменную экземпляра от заголовочного файла в Objective C

Я столкнулся с библиотекой, записанной в Objective C (у меня только есть заголовочный файл и.a двоичный файл). В заголовочном файле это похоже на это:

@interface MyClass : MySuperClass 
{ 
    //nothing here
}

@property (nonatomic, retain) MyObject anObject;
- (void)someMethod;

Как я могу достигнуть того же самого? Если я попытаюсь объявить свойство без его соответствующего ivar в интерфейсе {}, то компилятор даст мне ошибку. В конечном счете я хочу скрыть внутреннюю структуру своего класса в.a и просто выставить необходимые методы заголовочному файлу. Как я объявляю переменные экземпляра в.m? Категории не позволяют мне добавлять ivar, просто методы.

5
задан iamj4de 20 January 2010 в 18:25
поделиться

6 ответов

Существует много компонентов для запуска приложения как приложения ASP.Net. Тем не менее, с точки зрения вашего фактического проекта веб- Приложения, есть на самом деле не так много различий между ним и общим библиотечным кодом, за исключением того факта, что большая часть вашего кода зависит от существования среды выполнения (runtime), в которой работает (runtime), в которой работает (runtime), и в которой вы используете (runtime).

Любой код, использующий System.Web (особенно System.Web.UI), будет подозрительным с точки зрения наличия этой зависимости. Например, весь кодекс на странице или webcontrol обработчиках событий (Init, Груз, PreRender, и т.д.) полагается на то, что есть HttpHandler (бегущий в HttpApplication) подъем этих событий. Если запустить тот же WebControl из библиотеки, не входящей в проект ASP.Net, ничего из этого не произойдет, и элемент управления окажется бесполезным. Однако эта же библиотека была бы достаточно функциональной, если бы выполнялась в контексте процесса ASP.Net.

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

К сожалению, не существует простого пятиэтапного процесса преобразования веб-проекта в библиотеку. Но как правило, webcontrols, .aspx и .ascx codebehind не собираются конвертировать.

Для получения более подробной информации о том, что делает код программой ASP.Net, см. « A Low level look at ASP.Net » Рика Страла.

-121--4013150-

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

это будет проще, чем использовать клавишу автоматического приращения

-121--3367040-

Две возможности:

  1. Это может быть использование возможностей современной среды выполнения синтезировать переменные экземпляра, как предложил bbum.
  2. Свойство может не иметь базовой переменной экземпляра в этом классе. Свойства не обязательно имеют сопоставление один к одному с переменными экземпляра.
1
ответ дан 18 December 2019 в 05:26
поделиться

Для 64-битных приложений и приложений для iPhone (хотя и в синтезе имущества), синтез свойства также способен синтезировать хранилище для переменной экземпляра.

I.e. Это работает:

@interface MyClass : MySuperClass 
{ 
    //nothing here
}

@property (nonatomic, retain) MyObject *anObject;
@end

@implementation MyClass
@synthesize anObject;
@end

Если вы компилируете для 32-битной Mac OS X или симулятора iPhone, компилятор даст ошибку.

14
ответ дан 18 December 2019 в 05:26
поделиться

Нет, нельзя. Но вы можете сделать это, если не используете @property:

.h

@interface X : Y {
  struct X_Impl* impl;
}
-(int)getValue;
@end

.m

struct X_Impl {
  int value;
};
...
@implementation X
-(void)getValue {
  return impl->value * impl->value;
}
@end
1
ответ дан 18 December 2019 в 05:26
поделиться

Попробуйте использовать более простой метод [UIImage imageNamed: @ «navbar _ lavenape.png»] , поскольку элемент пользовательского интерфейса - это именно то, для чего предназначен imageNamed: , как показывает ljingeseATL.

-121--3855041-

Из конфигурации TinyMCE вы можете выбрать beavior новых строк

http://www.tinymce.com/wiki.php/Configuration3x: force _ br _ newlines

TinyMCE будет заставлять элементы BR на новых линиях вместо вставки абзацев

tinyMCE.init({
    ...
    force_br_newlines : true,
    force_p_newlines : false,
    forced_root_block : '' // Needed for 3.x
});
-121--3713418-

Как насчет макротрика?

Протестировали код ниже

  • протестировали dylibs - отработали прекрасно
  • протестировали подкласс - Предупреждение! сломается, я согласен, что это делает трюк не то чтобы полезным, но все же я думаю, что он рассказывает некоторые о том, как ObjC работает...

MyClass.h

@interface MyClass : NSObject {
#ifdef MYCLASS_CONTENT
    MYCLASS_CONTENT // Nothing revealed here
#endif
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int extra;
- (id)initWithString:(NSString*)str;
@end

MyClass.m

// Define the required Class content here before the #import "MyClass.h"
#define MYCLASS_CONTENT \
  NSString *_name; \
  int _extra; \
  int _hiddenThing; 

#import "MyClass.h"

@implementation MyClass
@synthesize name=_name;
@synthesize extra=_extra;

- (id)initWithString:(NSString*)str
{
    self = [super init];
    if (self) {
        self.name = str;
        self.extra = 17;
        _hiddenThing = 19;
    }
    return self;
}

- (void)dealloc
{
    [_name release];
    [super dealloc];
}

@end
0
ответ дан 18 December 2019 в 05:26
поделиться

НЕ делайте этого, но я считаю, что следует отметить, что среда выполнения имеет возможность добавлять ivars всякий раз, когда вы хотите, с помощью class_addIvar

0
ответ дан 18 December 2019 в 05:26
поделиться

Вы можете использовать ту же идиому, что и в классах Какао. Если вы посмотрите на интерфейс класса NSString в NSString.h, вы увидите, что переменная экземпляра не объявлена. Заглянув глубже в исходный код GNUstep, вы обнаружите уловку.

Рассмотрим следующий код.

MyClass.h

@interface MyClass : NSObject

// Your methods here
- (void) doSomething;

@end

MyClass.m

@interface MyClassImpl : MyClass {
   // Your private and hidden instance variables here
}
@end

@implementation MyClass

+ (id) allocWithZone:(NSZone *)zone
{
   return NSAllocateObject([MyClassImpl class], 0, zone);
}

// Your methods here
- (void) doSomething {
  // This method is considered as pure virtual and cannot be invoked
  [self doesNotRecognizeSelector: _cmd];          
}

@end

@implementation MyClassImpl

// Your methods here
- (void) doSomething {
  // A real implementation of doSomething
}

@end

Как видите, трюк заключается в перегрузке allocWithZone: в вашем классе. Этот код вызывается по умолчанию alloc , предоставленным NSObject , поэтому вам не нужно беспокоиться о том, какой метод распределения следует использовать (оба действительны). В таком allocWithZone: вы можете использовать функцию Foundation NSAllocateObject () для выделения памяти и инициализации isa для объекта MyClassImpl вместо MyClass . После этого пользователь прозрачно работает с объектом MyClassImpl .

Конечно, реальная реализация вашего класса должна быть предоставлена ​​ MyClassImpl . Методы для MyClass должны быть реализованы таким образом, чтобы получение сообщения рассматривалось как ошибка.

13
ответ дан 18 December 2019 в 05:26
поделиться