Remplacement d'une propriété en lecture seule dans la sous-classe

Il existe une classe qui ressemble à ça (je suis en omettant les importations pour des raisons de concision):

De Base.h:

@interface Base : NSObject
@property (strong, readonly) NSString *something;
- (id)initWithSomething:(NSString *)something;
@end

De Base.m:

@implementation Base
- (id)initWithSomething:(NSString *)something {
    self = [super init];
    if (self) _something = something;
    return self;
}
@end

Comme vous le voyez, le "quelque chose" de la propriété est en lecture seule. Maintenant, je veux créer une sous-classe qui l'emporte sur cette propriété pour être accessible en écriture ainsi:

Sous.h:

@interface Sub : Base
@property (strong) NSString *something;
@end

Sous.m:

@implementation Sub
@end

Et le code:

principal.c:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Sub *o = [Sub new];
        o.something = @"foo";
        NSLog(@"%@", o.something);
    }
    return 0;
}

Ce code:

    2013-09-07 13:58:36.970 ClilTest[3094:303] *** Terminating app due to uncaught
    exception 'NSInvalidArgumentException', reason: '-[Sub setSomething:]: unrecognized
    selector sent to instance 0x100109ff0'

Pourquoi est-ce? Pourquoi ne pas trouver le setSelector?

Quand je le fais dans la sous-classe à la place:

Sous.m:

@implementation Sub
@synthesize something = _something;
@end

tout cela fonctionne. Est-ce à dire que la sous-classe " la propriété n'est pas synthétisé par défaut, même si elle est définie comme @property dans le @interface? Ne le compiler en quelque sorte de "voir" l'générée automatiquement de lecture à partir de la Base et ne génère pas de setter? Et pourquoi, je pense que le mutateur doit être généré comme il n'existe pas encore. Je suis en utilisant Xcode 4.6.2 et le projet est un Outil Cli (type de Fondation), mais la même chose se passe dans mon projet actuel, qui est une application iPhone.

Contexte: j'ai un objet lourd (instance de Base) qui nécessite une connexion Bluetooth pour certains équipements et je suis censé créer une vue contrôleur pour certaines fonctionnalités. Pour tester facilement je ne veux pas être connecté à BT (en fait, j'aurais besoin d'un périphérique physique et tester le code sur elle), je voudrais être en mesure de le tester sur le simulateur.
Ce que j'ai trouvé, c'est que j'ai tout simplement créer une sous-classe (Sous -) que des talons de quelques méthodes /propriétés et l'utiliser à la place, et lorsque le code est prêt, je viens de supprimer le code pour la sous-classe, remplacer son exemple avec la bonne, test avec un appareil, commit et push. Il fonctionne bien, sauf pour ce qui est étrange avec @property ci-dessus.

Quelqu'un pourrait me dire ce qui se passe avec la propriété impérieuses?

  • En plus de la solution de travail, je voulais ajouter que " l'augmentation du niveau de la vie privée d'un attribut va à l'encontre des principes de la programmation orientée objet. Généralement (mais pas toujours), si vous devez faire un bien plus visible (privé -> protégé, ou, protégé -> public) dans une sous-classe, alors quelque chose est faux dans le modèle. Le contraire se produit avec des méthodes. Si le parent de la classe a Une méthode, vous ne devriez pas faire Un plus privé (public -> protégé, ou, protégé -> privé) dans une sous-classe.
InformationsquelleAutor wujek | 2013-09-07