Просто се чудех защо няма оптимизация на пула за автоматично освобождаване под ARC компилатора, където той ще запази обект в най-вътрешния обхват, ще го премахне от пула за автоматично освобождаване и ще го освободи, след като обектът вече не се използва?
За да цитирам много непрактичен пример от друг въпрос,
for(NSUInteger i = 0; i < 10000; i++)
{
for(NSUInteger j = 0; j < 10000; j++)
{
NSNumber* n = [NSNumber numberWithUnsignedInteger:j];
//NSLog(@"%@", n); //Disabled this to increase memory bloat faster.
}
}
Без @autoreleasepool { ... }
обвиване паметта расте и расте. При обвиване с @autoreleasepool
паметта остава ниска:
for(NSUInteger i = 0; i < 10000; i++)
{
for(NSUInteger j = 0; j < 10000; j++)
{
@autoreleasepool {
NSNumber* n = [NSNumber numberWithUnsignedInteger:j];
//NSLog(@"%@", n); //Disabled this to increase memory bloat faster.
}
}
}
Но защо компилаторът не може да оптимизира случаи като тези, където обектите няма да са необходими извън най-вътрешния обхват и да премахне необходимостта от @autoreleasepool
обвиване? Има ли техническа причина това да не е възможно или все още не е направено?
Редактиране
За да изясним защо компилаторът не може да изведе код като следния:
for(NSUInteger i = 0; i < 10000; i++)
{
for(NSUInteger j = 0; j < 10000; j++)
{
NSNumber* n = [NSNumber numberWithUnsignedInteger:j];
objc_retain(n);
objc_removeFromAutoreleasePool(n);
NSLog(@"%@", n);
objc_release(n);
}
}
Редактиране 2
По искане на Грег, ето резултатите от разглобяването на двата примера по-горе.
Без @autoreleasepool { }
:
TestOpt`-[LMViewController testAutoreleaseMem] at LMViewController.m:17:
0x2187: pushl %ebp
0x2188: movl %esp, %ebp
0x218a: pushl %ebx
0x218b: pushl %edi
0x218c: pushl %esi
0x218d: subl $0x1c, %esp
0x2190: calll 0x2195 ; -[LMViewController testAutoreleaseMem] + 14 at LMViewController.m:17
0x2195: popl %esi
0x2196: xorl %eax, %eax
0x2198: movl 0x13cb(%esi), %ebx
0x219e: movl %eax, -0x10(%ebp)
0x21a1: xorl %edi, %edi
0x21a3: movl 0x13df(%esi), %eax
0x21a9: movl %edi, 0x8(%esp)
0x21ad: movl %ebx, 0x4(%esp)
0x21b1: movl %eax, (%esp)
0x21b4: calll 0x227e ; symbol stub for: objc_msgSend
0x21b9: movl %eax, (%esp)
0x21bc: calll 0x2296 ; symbol stub for: objc_retainAutoreleasedReturnValue
0x21c1: movl %eax, (%esp)
0x21c4: calll 0x228a ; symbol stub for: objc_release
0x21c9: incl %edi
0x21ca: cmpl $0x2710, %edi
0x21d0: jne 0x21a3 ; -[LMViewController testAutoreleaseMem] + 28 at LMViewController.m:24
0x21d2: movl -0x10(%ebp), %eax
0x21d5: incl %eax
0x21d6: cmpl $0x2710, %eax
0x21db: jne 0x219e ; -[LMViewController testAutoreleaseMem] + 23 at LMViewController.m:24
0x21dd: addl $0x1c, %esp
0x21e0: popl %esi
0x21e1: popl %edi
0x21e2: popl %ebx
0x21e3: popl %ebp
0x21e4: ret
с:
TestOpt`-[LMViewController testAutoreleaseMem] at LMViewController.m:17:
0x216f: pushl %ebp
0x2170: movl %esp, %ebp
0x2172: pushl %ebx
0x2173: pushl %edi
0x2174: pushl %esi
0x2175: subl $0x1c, %esp
0x2178: calll 0x217d ; -[LMViewController testAutoreleaseMem] + 14 at LMViewController.m:17
0x217d: popl %ecx
0x217e: movl %ecx, -0x10(%ebp)
0x2181: xorl %eax, %eax
0x2183: movl 0x13e3(%ecx), %ecx
0x2189: movl %eax, -0x14(%ebp)
0x218c: xorl %edi, %edi
0x218e: movl %ecx, %ebx
0x2190: calll 0x2278 ; symbol stub for: objc_autoreleasePoolPush
0x2195: movl %eax, %esi
0x2197: movl -0x10(%ebp), %eax
0x219a: movl 0x13f7(%eax), %eax
0x21a0: movl %edi, 0x8(%esp)
0x21a4: movl %ebx, 0x4(%esp)
0x21a8: movl %eax, (%esp)
0x21ab: calll 0x227e ; symbol stub for: objc_msgSend
0x21b0: movl %eax, (%esp)
0x21b3: calll 0x2296 ; symbol stub for: objc_retainAutoreleasedReturnValue
0x21b8: movl %eax, (%esp)
0x21bb: calll 0x228a ; symbol stub for: objc_release
0x21c0: movl %esi, (%esp)
0x21c3: calll 0x2272 ; symbol stub for: objc_autoreleasePoolPop
0x21c8: incl %edi
0x21c9: cmpl $0x2710, %edi
0x21cf: jne 0x2190 ; -[LMViewController testAutoreleaseMem] + 33 at LMViewController.m:23
0x21d1: movl %ebx, %ecx
0x21d3: movl -0x14(%ebp), %eax
0x21d6: incl %eax
0x21d7: cmpl $0x2710, %eax
0x21dc: jne 0x2189 ; -[LMViewController testAutoreleaseMem] + 26 at LMViewController.m:24
0x21de: addl $0x1c, %esp
0x21e1: popl %esi
0x21e2: popl %edi
0x21e3: popl %ebx
0x21e4: popl %ebp
0x21e5: ret