จากที่ Xcode เปิด Automatic Reference Counting ...
ล่าสุด วันนี้ผมเขียนโค้ดซับซ้อนหน่อย ได้พบเจอปัญหา การอ้างอิงตัวแปร แบบไม่มีตัวตน หรือที่เรียกกันว่า ซอมบี้ครับ (ยังไม่เคยเจอ Memory leak เพราะ ARC มันจัดการได้ดีจริงๆ)
เจอ error exc bad access
ก็พยายามหาอ่านบทความเกี่ยวกับเรื่องนี้นะ
ปรกติ เวลาผมเขียนผมไม่ค่อยใส่ใจ แต่ถ้าเรามาลงมือถือ ก็ต้องสนใจมันละ เพราะเกี่ยวกับการจัดการ Memory เรื่องพวกนี้ เลยถือว่าเรื่องใหญ่มาก
--------
วันนี้ ที่เจอ คือ หลังจากประกาศ Object ไปแล้ว เรียกใช้ Object นั้นแบบ วนลูป หลายๆรอบ
ก็เจอ Zombie ทันที
ปวดหัวมาก
มันหา Property ไม่เจอ (Property แบบ Public)
หลังจาก หาทางแก้ไขไม่ได้ซ่ะที
เลยตัดสินใจ แก้โค้ด โดยทำ Property แบบ Private เวลาอ้างอิง ผมก็ทำ Setter และ Getter
สรุปแล้ว ปัญหา Zombie ก็หายไปทันที
ผมน่าจะอาจจยังงงๆ กับการ Retain ของเจ้าโปรแกรมนะ
--------------
ตัวอย่างโปรแกรม
@interface PeopleView: UIVIew
@property (nonatomic, strong) NSString *name;
+(id)peopleWithName: (NSString *)name;
- (id)initWithName: (NSString *)name;
@end
@implementation PeopleView
+(id)peopleWithName: (NSString *)name
{
return [[[self class] alloc] initWithName: name];
}
-(id)initWithName: (NSString *)name
{
self = [super initWithFrame...]
if ( self )
{
self.name = name;
}
return self;
}
@end
แบบเขียนแบบข้างบน เวลาประกาศตัวแปร แล้วเอาไปใส่ใน Array จัดการวนลูบ Object PreopleView หลายๆตัวออกมา
ถ้าอ้างอิง Property *name โดยตรง จะเกิด Zombie ครับ
ผมเลยแก้โดยการ เอาตัวแปร name ประกาศเป็น Private
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้จริงๆแล้ว ผมอาจจะสร้าง PrepleObject เป็น NSString ก็ดีนะครับ แต่แบบว่า ขี้เกียจแยก Object ออกไป เลยเอามารวมใน View
ผมไม่รุ้ว่า View กับ NSObject มันจะเกี่ยวกับการ Retain ด้วยหรือเปล่า
@interface PeopleView: UIVIew
-(NSString)getName;
-(void)setName: (NSString *)name
@end
@implementation PeopleView
{
NSString _name;
}
+(id)peopleWithName: (NSString *)name
{
return [[[self class] alloc] initWithName: name];
}
-(id)initWithName: (NSString *)name
{
self = [super initWithFrame...]
if ( self )
{
_name = name;
}
return self;
}
-(NSString)getName
{
return _name;
}
-(void)setName: (NSString *)name
{
_name = name;
}
@end
แบบนี้ ไม่ error ครับ
ผมสามารถอ้างอิง ตัวแปร _name ได้ตลอดเลย
โปรแกรมของผม ก็สามารถทำงานได้ตามเป้าหมาย
แต่ก็ใช้เวลาทั้งวัน ในการลองผิดลองถูก
อยากขอความกระจ่างแฮะ ไม่อยากให้ค้างคาใจ 555+
......กำลังทำความเข้าใจกับกับ Memory Leak, Zombie เกี่ยวกับการ Retain ของตัวแปรครับ
ล่าสุด วันนี้ผมเขียนโค้ดซับซ้อนหน่อย ได้พบเจอปัญหา การอ้างอิงตัวแปร แบบไม่มีตัวตน หรือที่เรียกกันว่า ซอมบี้ครับ (ยังไม่เคยเจอ Memory leak เพราะ ARC มันจัดการได้ดีจริงๆ)
เจอ error exc bad access
ก็พยายามหาอ่านบทความเกี่ยวกับเรื่องนี้นะ
ปรกติ เวลาผมเขียนผมไม่ค่อยใส่ใจ แต่ถ้าเรามาลงมือถือ ก็ต้องสนใจมันละ เพราะเกี่ยวกับการจัดการ Memory เรื่องพวกนี้ เลยถือว่าเรื่องใหญ่มาก
--------
วันนี้ ที่เจอ คือ หลังจากประกาศ Object ไปแล้ว เรียกใช้ Object นั้นแบบ วนลูป หลายๆรอบ
ก็เจอ Zombie ทันที
ปวดหัวมาก
มันหา Property ไม่เจอ (Property แบบ Public)
หลังจาก หาทางแก้ไขไม่ได้ซ่ะที
เลยตัดสินใจ แก้โค้ด โดยทำ Property แบบ Private เวลาอ้างอิง ผมก็ทำ Setter และ Getter
สรุปแล้ว ปัญหา Zombie ก็หายไปทันที
ผมน่าจะอาจจยังงงๆ กับการ Retain ของเจ้าโปรแกรมนะ
--------------
ตัวอย่างโปรแกรม
@property (nonatomic, strong) NSString *name;
+(id)peopleWithName: (NSString *)name;
- (id)initWithName: (NSString *)name;
@end
@implementation PeopleView
+(id)peopleWithName: (NSString *)name
{
return [[[self class] alloc] initWithName: name];
}
-(id)initWithName: (NSString *)name
{
self = [super initWithFrame...]
if ( self )
{
self.name = name;
}
return self;
}
@end
แบบเขียนแบบข้างบน เวลาประกาศตัวแปร แล้วเอาไปใส่ใน Array จัดการวนลูบ Object PreopleView หลายๆตัวออกมา
ถ้าอ้างอิง Property *name โดยตรง จะเกิด Zombie ครับ
ผมเลยแก้โดยการ เอาตัวแปร name ประกาศเป็น Private
[Spoil] คลิกเพื่อดูข้อความที่ซ่อนไว้
-(NSString)getName;
-(void)setName: (NSString *)name
@end
@implementation PeopleView
{
NSString _name;
}
+(id)peopleWithName: (NSString *)name
{
return [[[self class] alloc] initWithName: name];
}
-(id)initWithName: (NSString *)name
{
self = [super initWithFrame...]
if ( self )
{
_name = name;
}
return self;
}
-(NSString)getName
{
return _name;
}
-(void)setName: (NSString *)name
{
_name = name;
}
@end
แบบนี้ ไม่ error ครับ
ผมสามารถอ้างอิง ตัวแปร _name ได้ตลอดเลย
โปรแกรมของผม ก็สามารถทำงานได้ตามเป้าหมาย
แต่ก็ใช้เวลาทั้งวัน ในการลองผิดลองถูก
อยากขอความกระจ่างแฮะ ไม่อยากให้ค้างคาใจ 555+