请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

Objective-C 实现链表内存释放问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
//
//  LinkedList.h
//  ArrayList
//
//  Created by dzb on 2018/8/3.
//  Copyright © 2018 大兵布莱恩特. All rights reserved.
//
 
#import <Foundation/Foundation.h>
 
@interface LinkedList <ObjectType> : NSObject
 
- (void) addObjectAtFirst:(ObjectType)object;
 
- (void) addObjectAtLast:(ObjectType)object;
 
- (void) addObject:(ObjectType)object atIndex:(NSInteger)index;
 
- (void) updateObject:(ObjectType)object atIndex:(NSInteger)index;
 
- (BOOL) containObject:(ObjectType)object;
 
- (ObjectType) objectAtIndex:(NSInteger)index;
 
- (ObjectType) removeObjectAtIndex:(NSInteger)index;
 
- (ObjectType) removeFirstObject;
 
- (ObjectType) removeLastObject;
 
///count
@property (nonatomic,assign) NSInteger count;
///empty
@property (nonatomic,assign,getter=isEmpty,readonly) BOOL empty;
///firstObject
@property (nonatomic,strong,readonly) ObjectType firstObject;
///lastObject
@property (nonatomic,strong,readonly) ObjectType lastObject;
 
@end
 
//
//  LinkedList.m
//  ArrayList
//
//  Created by dzb on 2018/8/3.
//  Copyright © 2018 大兵布莱恩特. All rights reserved.
//
 
#import "LinkedList.h"
 
@interface Node < ObjectType > : NSObject
///ObjectType
@property (nonatomic,strong) ObjectType object;
///next
@property (nonatomic,strong) Node <ObjectType > *next;
 
+ (instancetype) nodeWithObject:(ObjectType)object nextNode:(Node <ObjectType> *)next;
 
+ (instancetype) nodeWithObject:(ObjectType)object;
 
- (instancetype) initWithObject:(ObjectType)object nextNode:(Node <ObjectType> *)next;
 
@end
 
@implementation Node
 
+ (instancetype)nodeWithObject:(id)object {
return [Node nodeWithObject:object nextNode:nil];
}
 
+ (instancetype)nodeWithObject:(id)object nextNode:(Node *)next {
return [[Node alloc] initWithObject:object nextNode:next];
}
 
- (instancetype)initWithObject:(id)object nextNode:(Node *)next {
if (self = [super init]) {
self.object = object;
self.next = next;
}
return self;
}
 
- (NSString *)description {
return [NSString stringWithFormat:@"Node : %p , object : %@",self,self.object];
}
 
 
@end
 
@interface LinkedList ()
 
///head
@property (nonatomic,strong) Node *dummyHead;
///size
@property (nonatomic,assign) NSInteger size;
 
@end
 
@implementation LinkedList
 
- (instancetype)init
{
self = [super init];
if (self) {
self.dummyHead = [[Node alloc] init];
self.size = 0;
}
return self;
}
 
- (void)addObjectAtFirst:(id)object {
//  Node *node = [Node nodeWithObject:object nextNode:self.head];
//  self.head = node;
//  self.size++;
[self addObject:object atIndex:0];
}
 
- (void)addObjectAtLast:(id)object {
[self addObject:object atIndex:self.size];
}
 
- (void)addObject:(id)object atIndex:(NSInteger)index {
if (index < 0 || index > self.count) {
@throw [NSException exceptionWithName:@"LinkedList is out of bounds" reason:@"Add failed. Illegal index." userInfo:nil];
return;
}
Node *prev = self.dummyHead;
for (int i = 0; i< index; i++) {
prev = prev.next;
}
prev.next = [Node nodeWithObject:object nextNode:prev.next];
self.size++;
}
 
 
- (id)objectAtIndex:(NSInteger)index {
if (index < 0 || index >= self.count) {
@throw [NSException exceptionWithName:@"LinkedList is out of bounds" reason:@"Add failed. Illegal index." userInfo:nil];
return nil;
}
 
Node *cur = self.dummyHead.next;
for (int i = 0; i<index; i++) {
cur = cur.next;
}
 
return cur.object;
}
 
- (id)firstObject {
return [self objectAtIndex:0];
}
 
- (id)lastObject {
return [self objectAtIndex:self.count-1];
}
 
- (void)updateObject:(id)object atIndex:(NSInteger)index {
if (index < 0 || index >= self.count) {
@throw [NSException exceptionWithName:@"LinkedList is out of bounds" reason:@"Add failed. Illegal index." userInfo:nil];
return;
}
Node *cur = self.dummyHead.next;
for (int i = 0; i<index; i++) {
cur = cur.next;
}
cur.object = object;
}
 
- (BOOL)containObject:(id)object {
Node *cur = self.dummyHead.next;
while (cur != NULL) {
if ([cur.object isEqual:object])
return YES;
cur = cur.next;
}
return NO;
}
 
 
- (id) removeObjectAtIndex:(NSInteger)index {
if (index < 0 || index >= self.count) {
@throw [NSException exceptionWithName:@"LinkedList is out of bounds" reason:@"Add failed. Illegal index." userInfo:nil];
return nil;
}
 
Node *prev = self.dummyHead;
for (int i = 0; i<index; i++) {
prev = prev.next;
}
 
Node *retNode = prev.next;
prev.next = retNode.next;
retNode.next = NULL;
return retNode.object;
 
}
- (id) removeFirstObject {
return [self removeObjectAtIndex:0];
}
 
- (id) removeLastObject {
return [self removeObjectAtIndex:self.count-1];
}
 
 
- (NSInteger)count {
return self.size;
}
 
- (NSString *)description {
 
NSMutableString *string = [NSMutableString stringWithFormat:@"\nLinkedList %p : [ \n" ,self];
Node *cur = self.dummyHead.next;
while (cur != nil) {
[string appendFormat:@"%@ -> \n",cur];
cur = cur.next;
}
[string appendString:@"NULL\n"];
[string appendString:@"]\n"];
 
return string;
}
 
- (BOOL)isEmpty {
return self.count == 0;
}
 
- (void)dealloc
{
 
}
@end
 
测试代码 :
 
- (void) testArray {
     
    NSTimer *timer = [NSTimer timerWithTimeInterval:3.0f target:self selector:@selector(test) userInfo:nil repeats:NO];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    _timer = timer;
    _timeArray = [NSMutableArray array];
 
}
 
- (void) test {
    static int count = 0;
    if (count > 9) {
        [_timer invalidate];
        _timer = nil;
        NSLog(@"time is %@",[_timeArray valueForKeyPath:@"@avg.self"]);
        return;
    }
 
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
        int number = 100000;
        Person *p = [Person new];
        LinkedList <Person *> *linked = [[LinkedList alloc] init];
        for (int i = 0; i<number; i++) {
            [linked addObjectAtFirst:@(i)];
        }
        NSLog(@"%@",linked);
        CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
        CFTimeInterval duration = linkTime * 1000.0f;
        NSLog(@"Linked in %f ms",duration);
//      self->_linkedList = linked;
        [self->_timeArray addObject:@(duration)];
        count++;
    });
     
}
 
 
当链表添加元素个人超过800时候 发现打印链表时候数据有丢失 比如添加1...800  打印只有100...800 ,前边的0-99 数据不见了. 当添加超过800个元素时候 会出现内存释放问题 ,我的猜测时当没有强引用指向这个链表时候 ,同时对大量的对象 release 时候出错了.  
 
由于实在找不到原因,只能是猜测链表内部节点在释放内存时候出了问题. 于是我将链表内部的 Node 由对象改成 C 语言 结构体
 
typedef id AnyObject;
 
typedef struct node {
    __unsafe_unretained AnyObject data;
    struct node *next;
} Node; 
 
改进后的链表内存释放改为手动释放内存,没有发现节点数据丢失和内存释放的问题.
希望波波老师有时间把我上边 Objective-C 实现的链表代码 运行下, 可能 Java 是自动管理内存吧,在学习动态数组时候 没有见波波老师释放过内存,我自己写的动态数组 也是用的 C 语言数组,然后手动管理存入数组的对象内存引用计数.
1
<br>


正在回答 回答被采纳积分+3

插入代码

1回答

liuyubobobo 2018-08-04 22:54:37

抱歉,我已经超过5年不写OC了,看不动OC代码了。。。


这个课程讲数据结构原理,视频语言是Java语言。请允许我不能帮助所有同学用任意语言实现的代码调程序。。。望谅解。


抱歉。加油!:)

0 回复 有任何疑惑可以回复我~
  • 提问者 qq_叫兽_1 #1
    波波老师 我用 C 语言的结构体指针完成的链表实现 能够有效的管理 OC 引用计数 但是整体实现思路还是跟着波波老师讲的一样的. 虽然有点小郁闷 但是不影响最终实现的功能
    回复 有任何疑惑可以回复我~ 2018-08-05 12:44:29
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号