在某些情况下,您可能会覆盖超类的属性.
您声明一个属性与其超类的名称和属性相同.(因为如果您更改属性,则可以获得编译器警告).您可以使用您创建的ivar进行合成.这有什么用?或者它有什么危害呢?
如果超类在类扩展(没有名称的类别)中声明属性,则它可能不在头文件中.如果您不知道头文件中的该属性,则可以使用您想要的属性或类声明相同的名称属性.但是setter/getter方法将覆盖那个"秘密属性"的方法.我认为这只会造成伤害.但既然你不知道头文件,你怎么能避免这个?
您可以将头文件中的属性声明为"readonly",并在类扩展中将其重新声明为"readwrite".我认为这是可以做得好的情况.
我对这些情况的了解是否正确?我不知道第一和第二种情况可以做些什么.但是如果我想避免第一种情况,我可以在声明之前检查子类是否已经具有该属性.但是如果属性不在公共头文件中,就像在第二种情况下那样,我只是不知道该怎么做.
我知道声明属性生成存取方法,这只是语法糖.
我发现self.property = nil他们的dealloc方法中有很多人使用它.
1)在Apple的内存管理文档中,p23它说:
您不应该使用访问器方法来设置实例变量的唯一地方是init方法和dealloc.
为什么不呢?
2)在Apple的Objective-C 2.0,p74中
声明的属性从根本上取代了访问器方法声明; 在合成属性时,编译器仅创建任何缺少的访问器方法.没有与
dealloc方法直接交互 - 不会自动为您释放属性.但是,声明的属性提供了一种交叉检查dealloc方法实现的有用 方法:您可以在头文件中查找所有属性声明,并确保未标记的对象属性assign被释放,并且标记的 对象属性不会assign被释放.注意:通常在
dealloc方法中,您应该release直接对象实例变量(而不是调用set访问器并nil作为参数传递),如下例所示:
- (void)dealloc { [property release]; [super dealloc]; }
Run Code Online (Sandbox Code Playgroud)
但是,如果使用现代运行时并合成实例变量,则无法直接访问实例变量,因此必须调用访问器方法:
- (void)dealloc { [self setProperty:nil]; [super dealloc]; }
Run Code Online (Sandbox Code Playgroud)
这个音符是什么意思?
我找到了[property release];并且[self setProperty:nil];都工作了.
Apple说:
重要:多个线程不能使用ABAddressBookRef的实例.每个线程都必须创建自己的实例.
但为什么?
我知道必须在主线程中完成一些特定的类或操作.
我知道有些对象不是线程安全的(这意味着如果这两个不同的线程同时访问这些对象会导致问题).
但是,如果你可以确保任何时刻只有一个线程访问线程不安全的对象,那么应该没有问题.
到目前为止我能理解正确吗?
我无法理解的是,为什么需要为每个线程创建像ABAddressbookRef这样的对象?为什么苹果会说这样的话?如果它只是线程不安全,Apple可以说它不安全,在处理它时要小心.但为什么需要为每个线程创建一个?我有什么理由不知道吗?
ABAddressbookRef的实现是否依赖于创建它的线程?
PS:我记得Core Data还说需要为每个使用它的线程创建ManagedObjectContext.
如果我得到一个NSData,我知道它是图像的数据.但我不知道它是什么格式.那么如何识别它的图像格式呢?Jpeg还是PNG?
PS:iOS版
在许多关于如何使用块和GCD的指南中,总是提到一个提示:不要在块中保留self.
细节是在定义一个块时,如果你引用self或者我自己的ivar,那么block会保留self.因此,解决方法是使用__block修饰符来获取weakSelf或weakIvar.
但是不这样做有什么害处呢?如果块保留自我,它应该在块完成时释放自我(我是否正确?).因此,最终自我的参考计数是平衡的.我知道如果自我保留了块并且块保留了自身,那么它将是一个保留周期.块和self都将被解除分配.但是如果使用GCD,自我不保留块,为什么不让块保留自己?
类扩展的一个强大优势是,使用类扩展,您可以在头文件中声明readonly属性,并在类扩展中将此属性覆盖为readwrite属性.如下所示:
//SomeClass.h
@interface SomeClass : NSObject
{
NSInteger someInt; //with modern runtime you can omit this line
}
@property (readonly) NSInteger someInt;
@end
//SomeClass.m
@interface SomeClass ()
@property (readwrite) NSInteger someInt;
@end
@implementation SomeClass
@synthesize someInt;
@end
Run Code Online (Sandbox Code Playgroud)
但是如果你使用现代运行时,你也可以在类扩展中声明一个全新的属性(如果没有,也为该属性生成一个iVar).
//SomeClass.h
@interface SomeClass : NSObject
{
}
@end
//SomeClass.m
@interface SomeClass ()
@property (readwrite) NSInteger someInt;
@end
@implementation SomeClass
@synthesize someInt;
@end
Run Code Online (Sandbox Code Playgroud)
这是我的问题:我认为在课堂扩展中声明一个全新的属性在某种程度上会产生一些副作用.因为类扩展我不在头文件中,而另一个继承类的人可能不知道那个"秘密属性".如果他宣布一个与该"秘密财产"同名的财产.而这个新属性的getter和setter方法将覆盖超类.这不是问题吗?为什么现代运行时会允许这样的事情发生?
编辑我发布了关于这个主题的另一个问题,请查看: 在类扩展(Ojbective-C)中声明新的propery的风险,如何解决?
GCD是否确保在同一队列中工作的所有块始终在同一个线程中工作?
如果我为此队列创建一个调度队列和dispath_async块,那么调度到该队列的所有块是否都在同一个线程中工作?
由于我正在开发一个使用ABAdrressbook Framerowk的项目,并且该文档说不能在线程之间使用ABAddressBookRef和ABRecordRef,所以我想知道队列中的所有块是否都在同一个线程中,我只能创建一个AddressBookRef为那个队列.
thread-safety addressbook grand-central-dispatch objective-c-blocks
objective-c ×5
properties ×3
addressbook ×1
dealloc ×1
image ×1
ios ×1
jpeg ×1
nsdata ×1
null ×1
overriding ×1
png ×1
trailing ×1