在类别中声明属性

除了扩展之外,其他类别都无法向类中新增实例变量,所以,编译器无法把实现属性所需的实例变量合成出来。

从概念上讲,属性是封装数据的方式。类别是扩展类功能的手段,而非封装数据。因此,一般情况下应该避免把属性声明在类别中,而应该声明在“主接口”中。

如果不得不这么做的话,可以使用关联对象辅助实现:

//
//  NimoPerson+Friendship.h
//  PersonDemo
//
//  Created by Tony on 15/8/17.
//  Copyright (c) 2015年 NimoWorks. All rights reserved.
//

#import "NimoPerson.h"

@interface NimoPerson (Friendship)

@property (nonatomic, strong) NSArray *friendsArray;

@end
//
//  NimoPerson+Friendship.m
//  PersonDemo
//
//  Created by Tony on 15/8/17.
//  Copyright (c) 2015年 NimoWorks. All rights reserved.
//

#import "NimoPerson+Friendship.h"
#import <objc/runtime.h>

static const char *kFriendsPropertyKey = "kFriendsPropertyKey";

@implementation NimoPerson (Friendship)

- (NSArray *)friendsArray {
    return objc_getAssociatedObject(self, kFriendsPropertyKey);
}

- (void)setFriendsArray:(NSArray *)friendsArray
{
    objc_setAssociatedObject(self, kFriendsPropertyKey, friendsArray, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

需要特别留意的是设置方法中的内存管理语义:

关联类型 等效的@property属性

OBJC_ASSOCIATION_ASSIGN

assign

OBJC_ASSOCIATION_RETAIN_NONATOMIC

nonatomic, retain

OBJC_ASSOCIATION_COPY_NONATOMIC

nonatomic, copy

OBJC_ASSOCIATION_RETAIN

retain

OBJC_ASSOCIATION_COPY

copy
时间: 2024-11-10 07:43:21

在类别中声明属性的相关文章

第26条:勿在分类中声明属性

属性是封装数据的方式(参见第6条). 属性只是定义实例变量及相关存取方法所用的“语法糖”,所以也应遵循同实例变量一样的规则. 分类机制,应该将其理解为一种手段,目标在于扩展类的功能,而非封装数据. 尽管从技术上说,分类里也可以声明属性,但这种做法应该尽量避免. 原因是:除了“class-continuation分类”(参见第27条)之外,其他分类都无法向类中新增实例变量,因此,它们无法把实现属性所需的实例变量合成出来. 所以开发者需要在分类中为该属性实现存取方法. 1)此时可以把方法声明为@dy

iOS OC 避免在分类中声明属性

一 描述      尽管从技术上来说,分类里可以声明属性,但是这种做法还是要尽量避免,原因在于,除了 class-continuation 分类(延展)之外,其他分类都无法向类中新增实例变量,因此,他们无法把实现属性所需的实例变量合成出来. 正确做法是把所有属性都定义在主接口中,这是唯一能够定义实例变量的地方.而属性只是定义实例变量及相关存取方法所用的"语法糖",所有也应遵循同实例变量一样的规则. 至于分类机制,则应该将其理解为一种手段,目标在于扩展类的功能,而非封装数据 二 总结  

类别中使用属性的两种方法

类别因不能添加实例变量,所以添加属性不能生成实例变量也不能自动生成setter跟getter方法,但可以自己实现setter跟getter方法. 第一种使用属性的方法:自己实现setter跟getter方法,用参数的值判断对主类中实例变量做一些操作. .h文件代码: #import "Fimaly.h" @interface Fimaly (Play) @property (nonatomic,assign) int age; @end .m文件代码 #import "Fim

iOS 类别中使用属性

iOS扩展属性:category可以扩展类的方法,但是不能扩张类的属性.如果要扩展类的属性,可以用associative,这个相对于category来说用的比较少,而且他还用到运行时编程,必须使用<obj/runtime.h>,使用objc_getAssociatedObject,objc_setAssociatedObject以及objc_removeAssociatedObjects.这几个方法的生命如下: 示例代码如下: 1.先创建一个person类 #import <Founda

iOS 声明属性关键字讲解

atomic: 原子操作(原子性是指事务的一个完整操作,操作成功就提交,反之就回滚. 原子操作就是指具有原子性的操作)在objective-c 属性设置里面 默认的就是atomic ,意思就是 setter /getter函数是一个原子操作,如果多线程同时调用setter时,不会出现某一个线程执行完setter所有语句之前,另一个线程就开始执行setter,相当于 函数头尾加了锁 . 这样的话 并发访问性能会比较低 . nonatomic: 非原子操作 一般不需要多线程支持的时候就用它,这样在 

iOS 声明属性关键字的总结

atomic: 原子操作(原子性是指事务的一个完整操作,操作成功就提交,反之就回滚. 原子操作就是指具有原子性的操作)在objective-c 属性设置里面 默认的就是atomic ,意思就是 setter /getter函数是一个原子操作,如果多线程同时调用setter时,不会出现某一个线程执行完setter所有语句之前,另一个线程就开始执行setter,相当于 函数头尾加了锁 . 这样的话 并发访问性能会比较低 . nonatomic: 非原子操作 一般不需要多线程支持的时候就用它,这样在 

ASP.NET MVC中实现属性和属性值的组合,即笛卡尔乘积01, 在控制台实现

在电商产品模块中必经的一个环节是:当选择某一个产品类别,动态生成该类别下的所有属性和属性项,这些属性项有些是以DropDownList的形式存在,有些是以CheckBoxList的形式存在.接着,把CheckBoxList的选中项组合生成产品SKU项. 本系列将在ASP.NET MVC中实现以上功能.但本篇,先在控制台实现属性值的笛卡尔乘积. 关于属性的类: public class Prop { public int Id { get; set; } public string Name {

多对多的属性对应表如何做按照类别的多属性匹配搜索

电商设计中常用到的属性对应表需要做按照类别的多属性匹配功能,举例建表如下 CREATE TABLE goods_attr ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id', `goods_id` int(11) DEFAULT '0' COMMENT '商品id', `type` int(11) DEFAULT '0' COMMENT '属性类型:1:商品类型 2:支持语言 3:支持平台', `value` varcha

【转载】在Javascript中 声明时用&quot;var&quot;与不用&quot;var&quot;的区别

原文链接:http://www.2cto.com/kf/201204/128406.html[侵删] Javascript声明变量的时候,虽然用var关键字声明和不用关键字声明,很多时候运行并没有问题,但是这两种方式还是有区别的 Javascript声明变量的时候,虽然用var关键字声明和不用关键字声明,很多时候运行并没有问题,但是这两种方式还是有区别的.可以正常运行的代码并不代表是合适的代码. var num = 1: 是在当前域中声明变量. 如果在方法中声明,则为局部变量(local var