Есть ли способ добавить iVar, которого нет в заголовочном файле (не использующий LLVM 2.0 или более позднюю версию) в Objective-C? - PullRequest
2 голосов
/ 12 апреля 2011

Я недавно узнал, что вы можете добавить ivar в расширение класса с LLVM2.0. (GCC не может этого сделать) Это как-то действительно приватный iVar, потому что другие пользователи не знают о его существовании, поскольку его нет в заголовочном файле. как:

//SomeClass.h
@interface SomeClass : NSObject {

}
@end

//SomeClass.m
@interface SomeClass ()
{
    NSString *reallyPrivateString;
}
@end

@implementation SomeClass

@end

Но это зависит от компилятора. Есть ли другой способ объявить ивара, которого нет в заголовочном файле?

Ответы [ 3 ]

1 голос
/ 12 апреля 2011

Единственное место, чтобы объявлять переменные экземпляра - это интерфейс или расширение класса (которое на самом деле является расширением интерфейса). Но вы можете эффективно добавлять переменные экземпляра в любое время с помощью современной среды выполнения, используя связанные функции объекта .

0 голосов
/ 12 апреля 2011

Если вы просто собираетесь использовать ivar для внутренних целей и используете современную среду выполнения (Snow Leopard 64 bit и iOS 3.0+, я думаю), тогда вы можете просто объявить свойства в расширении класса и синтезировать их внутри класса. В вашем заголовке нет иваров, нет грязных id _internal объектов, и вы можете обойти хрупкие ивары.

// public header
@interface MyClass : NSObject {
// no ivars
}
- (void)someMethod;
@end

// MyClass.m
@interface MyClass ()
@property (nonatomic, retain) NSString *privateString;
@end

@implementation MyClass
@synthesize privateString;

- (void)someMethod { 
    self.privateString = @"Hello";
    NSLog(@"self.privateString = %@", self.privateString);
    NSLog(@"privateString (direct variable access) = %@", privateString); // The compiler has synthesized not only the property methods, but also actually created this ivar for you. If you wanted to change the name of the ivar, do @synthesize privateString = m_privateString; or whatever your naming convention is
}
@end

Это работает с gcc от Apple, в дополнение к LLVM. (Я не уверен, что это работает на других платформах, т.е. не на gcc от Apple, но, безусловно, будет работать как для iOS, так и для Snow Leopard +).

0 голосов
/ 12 апреля 2011

Если вы реализуете библиотеку и хотите скрыть переменные экземпляра, взгляните на то, что Apple делает в интерфейсе для UIWebView. У них есть внутреннее веб-представление, которое не предоставляет заголовочный файл.

@class UIWebViewInternal;
@protocol UIWebViewDelegate;

UIKIT_CLASS_AVAILABLE(2_0) @interface UIWebView : UIView <NSCoding, UIScrollViewDelegate> { 
 @private
    UIWebViewInternal *_internal;
}
...