Добавить BOOL недвижимость через категорию - программирование
Подтвердить что ты не робот

Добавить BOOL недвижимость через категорию

Я использую категорию NSAttributedString (Additions) и мне действительно нужен способ добавить свойство, которое будет BOOL (указывая, является ли строка тегом HTML или нет). Я знаю, что у категорий не должно быть свойств, но именно так, как мне нужно. Я устал писать свои собственные методы получения и установки, но это не сработало. Как это может работать?

4b9b3361

Ответ 1

Для полноты, вот как я получил это для работы:

@interface

@interface ClassName (CategoryName)
@property (readwrite) BOOL boolProperty;
@end

@implementation

#import <objc/runtime.h>

static char const * const ObjectTagKey = "ObjectTag";
@implementation ClassName (CategoryName)
- (void) setBoolProperty:(BOOL) property
{
    NSNumber *number = [NSNumber numberWithBool: property];
    objc_setAssociatedObject(self, ObjectTagKey, number , OBJC_ASSOCIATION_RETAIN);
}

- (BOOL) boolProperty
{
    NSNumber *number = objc_getAssociatedObject(self, ObjectTagKey);
    return [number boolValue]; 
}
@end

Ответ 2

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

Вы можете добавить метод категории (представленный только для свойства чтения) isHTMLTag, который вернет BOOL, вам просто нужно будет вычислить, был ли он HTML-тегом каждый раз в этом методе.

Если вы запрашиваете способ установить значение BOOL, вам нужно будет использовать связанные ссылки (objc_setAssociatedObject), которые я никогда не использовал, поэтому не чувствуйте себя готовыми ответить более подробно.

Ответ 3

Мое решение без необходимости использовать ключ объекта и немного легче читать синтаксис

NSString + helper.h

#import <Foundation/Foundation.h>

@interface NSString (Helper)

@property (nonatomic, assign) BOOL isHTML;

@end

NSString + helper.h

#import "NSString+Helper.h"
#import "objc/runtime.h"

@implementation NSString (Helper)

- (void)setIsHTML:(BOOL)isHTML
{
    NSNumber *isHTMLBool = [NSNumber numberWithBool:isHTML];
    objc_setAssociatedObject(self, @selector(isHTML), isHTMLBool, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)isHTML
{
    NSNumber *isHTMLBool = objc_getAssociatedObject(self, @selector(isHTML));
    return isHTMLBool.boolValue;
}

@end

Ответ 4

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

Ответ 5

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

@interface ClassName (CategoryName)
    @property (class) id myProperty;
@end

@implementation
static id *__myProperty = nil;

+ (id)myProperty {
    return __myProperty;
}

+ (void)setMyProperty:(id)myProperty {
    __myProperty = myProperty;
}

@end

Из примечаний к выпуску Xcode 8:

Objective-C теперь поддерживает свойства класса, которые взаимодействуют с Свойства Swift. Они объявляются как: @property (класс) NSString * someStringProperty;. Они никогда не синтезируются. (23891898)

Ответ 6

Свифт 3:

Используя этот метод, вы можете добавить любое новое свойство (здесь добавить значение Bool) в захватывающий класс.

import ObjectiveC

private var xoAssociationKey: UInt8 = 0

extension <ClassName> {
    var <propertyName>: Bool! {
        get {
            return objc_getAssociatedObject(self, &xoAssociationKey) as? Bool ?? false
        }
        set(newValue) {
            objc_setAssociatedObject(self, &xoAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        }
    }
}