@ динамическое свойство в Objective C - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь реализовать свойство Dynamic в моем проекте Это мой код

MyClass.h

@interface MyClass : UIView

@property (strong, nonatomic) NSString *name;

@end

MyClass.m

@implementation MyClass

@dynamic name;

-(void)setName:(NSString *)name{
   self.name = name;
}
@end

Но при запуске приложение перестало работать.

enter image description here

Когда я использую ивар, была эта ошибка. enter image description here

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018

Этот ответ StackOverflow: https://stackoverflow.com/a/1160545/7833793 хорошо объясняет разницу между @synthesize и @dynamic. Обычно вы используете @dynamic, если делегируете задачу реализации методов доступа (get, set). Мне кажется, что вы хотели бы использовать здесь @synthesize. Но с современной целью c вам даже не нужно указывать, и iVar будет создан для вас автоматически.

т.е:.

MyClass.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyClass : NSObject
@property (strong, nonatomic) NSString *name;
@end

NS_ASSUME_NONNULL_END

MyClass.m

#import "MyClass.h"

@implementation MyClass

- (void)setName:(NSString *)name {
    _name = name;
}

@end
0 голосов
/ 18 сентября 2018

Свойство - это просто набор из двух методов: геттер и сеттер. Итак, когда вы пишете

@property (strong, nonatomic) NSString *name;

что вы на самом деле говорите, это

- (NSString *)name;
- (void)setName:(NSString *)name;

После этого каждый раз, когда компилятор встречает выражение вида obj.name, он переводит его в [obj name]. И каждый раз, когда вы видите выражение типа obj.name = @"hello";, компилятор переводит его в [obj setName:@"hello"].

Следующее, что вы должны убедиться, что свойство ведет себя правильно. У вас есть много вариантов:

  • Пишите геттеры и сеттеры вручную, ссылаясь на iVar
  • Синтезировать геттер и сеттер
  • Автосинтез геттера и сеттера
  • Запись пользовательских геттеров и сеттеров
  • Используйте @dynamic, чтобы избежать предупреждений во время компиляции, потому что вы намерены делать магию во время выполнения. (Действительно, это не то, что вы хотите сделать, потому что сначала вам нужно понять основы.)

Пишите геттеры и сеттеры вручную, ссылаясь на iVar

@interface MyClass : UIView {
    NSString *_name;
}

@property (strong, nonatomic) NSString *name;

@end

и в реализации

@implementation MyClass

- (NSString *)name {
    return _name;
}
- (void)setName:(NSString *)name {
    _name = name;
}

@end

Синтезировать геттер и сеттер

Последний раздел в основном эквивалентен этому

@interface MyClass : UIView {
    NSString *_name;
}

@property (strong, nonatomic) NSString *name;

@end

@implementation MyClass

@synthesize name = _name;

@end

Автосинтез геттера и сеттера

На практике вы просто используете "автосинтезирование".

@interface MyClass : UIView

@property (strong, nonatomic) NSString *name;

@end

@implementation MyClass

@end

Это значит,

  • если вы просто объявите свойство
  • не звоните @synthesize или @dynamic
  • не реализовывать никаких пользовательских методов получения и установки

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

Это означает, что первые два и этот разделы эквивалентны, потому что они производят один и тот же код.

Запись пользовательских геттеров и сеттеров

Вот что на самом деле означает термин «динамическое свойство». Например, вы можете захотеть, чтобы имя всегда было в верхнем регистре. Таким образом, вы можете написать свойство как это.

@interface MyClass : UIView {
    NSString *_name;
}

@property (copy, nonatomic) NSString *name;

@end

@implementation MyClass

- (NSString *)name {
    return _name;
}

- (void)setName:(NSString *)name {
    _name = [name uppercaseString];
}

@end

(в приведенном выше коде я изменил strong на copy - не волнуйтесь, это в любом случае просто комментарий. И это действительно так, потому что uppercaseString никогда не будет прежним, он будет всегда быть копией оригинала.)

Это, пожалуй, единственный действительно интересный случай! Например, этот тип свойств - то, что UIKit использует все время, например. text свойство UILabel является таким динамическим свойством. Он не только устанавливает некоторые значения iVar, но также гарантирует, что видимый текст на экране также изменится.

@dynamic свойства

их действительно сложно понять правильно, и большую часть времени они не стоят хлопот ИМХО.

Примечание: я упростил некоторые вещи и пропустил детали, которые можно обнаружить только при использовании API проверки времени выполнения objc

0 голосов
/ 18 сентября 2018

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

-(void)setName:(NSString *)name{
   _name = name;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...